Swift App项目总结
最近公司新开了一个项目,由于我的同事的离职,所以就剩我自己了。于是就果断的使用纯纯Swift写了,之前也用过Swift,不过很早了,那时候Swift还不稳定,每次一升级Xcode,Swift升级以后语法也跟着变了,所以就多了一堆的警告。现在Swift进化到3.X了,Swift众多新特性的支持,让我果断的要投入生产环境使用了。
这篇博客是项目上线了,可以有两天的空闲时间了,可以写写博客了,记录一下第一个Swift项目遇到的一些问题。也会顺带开源一些我写的小控件,大家可以参考或者使用一下。
Tips
1.webkit相关
内置的浏览器抛弃webview升级到了webkit,内存等各方面都要比之前好很多。不同的地方是还要实现WKUIDelegate的协议,因为alert弹窗都是需要你实现协议了,这样更能让自己的app的web部分和原生部分样式等方面的统一。不过和前端交互的时候需要我这边自定义User-Agent(UA),以确定到底是在哪打开(微信,android,其它手机浏览器?)的。WKWebView有个属性是customUserAgent,不过遗憾的是只能在iOS9.0以上使用,我还要兼容iOS8呢。
不过我喜欢把这种配置单独的在程序的某个单例里面,这样即使有多个包裹WKWebView的controller也可以统一配置(在程序启动的时候执行一下了事)。因为我还不想破坏掉原有的UA,我只是想在保留原有的UA的基础上,在符合UA规则下添加一条自定义的参数即可,毕竟完全自定义UA在访问其他站点的时候可能会有浏览器识别问题。基于这两点就踩了一个坑:
WKWebView有个方法可以获取当点的默认UA
open func evaluateJavaScript(_ javaScriptString: String, completionHandler: ((Any?, Error?) -> Swift.Void)? = nil)
但是因为是通过回调的方式,虽然WKWebView已经晚于设置UA好久了,还是会有不能生效的问题,只有第二次new WKWebView的对象才可以,很奇怪。无奈啊,后来想到了之前的UIWebView,在那个全局配置的单例里面通过
open func stringByEvaluatingJavaScript(from script: String) -> String?
获取设备默认的UA,然后拼接字符串,然后再通过设置
UserDefaults.standard.register(defaults: ["UserAgent": newUA])
就可以了。
2.String转Class
这次也把我之前的一篇博客的iOS controller解耦探究实现——第一次写博客OC代码用Swift重写。
这个东西的主要原理就是通过String转Class,这个要用到OC的Runtime(感觉还是离不开这种拥有魔法黑科技的Runtime啊),结果String不是单单的ClassName了,需要添加App本身的Bundle name加英文点号再加ClassName。具体的苹果官方文档有说明。示例如下:
let myPersonClass: AnyClass? = NSClassFromString("MyGreatApp.Person")
暂时就想起来了以上2个小Tips,以后想起来再做补充吧
Swift开源库
SwiftyJSON
用过Swift原生的解析json就知道了,因为Swift引入了optional,虽然使得Swift比OC更安全了,但是对于多层级的json取值简直能折磨死人。用了SwiftyJSON,感觉整个Swift的json解析再也不是问题了。强烈安利使用,看看这个库的源代码,基本也能学习不少知识呢。
Kingfisher
一个Swift的图片下异步加载缓存模块,作者也是说了受SDWebImage的启发。写的也非常棒,效果也很好。当然因为要配合我自己的一个banner轮播图控件,我修改了一下源代码(仅仅修改了图片的缓存文件夹),哈哈,我的修改版也放在了我的GitHub,在cunstom分支里面。
可以在CocoaPods这样引用就可以了
pod 'Kingfisher', :git => 'https://github.com/ysk666666/Kingfisher.git', :branch => 'custom'
PS:一开始我都用了SDWebImage了,也写了很多的逻辑了,但是后来发现了这个库后,看了一下代码,真的很棒,然后又用了一个小时把之前的逻辑都迁移到了Kingfisher 上面,😅。另外这个库的作者真的是大神,每次看他的博客感觉都能收获很多
JXPhotoBrowser
这是一个Swift写的大图浏览器,感觉写的很棒,逻辑也很严谨,动画效果也很好。也很值得推荐,当然大家看到不错的也可以评论推荐。图片加载是也是基于Kingfisher
我也要贡献点东西
YRouter的改进&Swift版本
代码在我的GitHub: YRouterSwiftDemo
这个其实本质上就是借助String转Class,然后这个String来源于URL的host,所以URL的host部分必须和VC的名字保持一致(URL的scheme可以随便自定义),这样就再也不用像之前的时候每写一个VC都要去某个地方注册一下,不过各有利弊。原来的那种方式可以定义比较短的host,常用的VC跳转写起来会很方便。
原理的另外一部分是给系统的UIViewController通过Runtime模拟属性的方式,添加了一个any类型的parameter。这个就是用来往目标VC传递参数的,具体的格式可以自定义,或者跟同事约定好,基本就可以了。
直接把demo的class文件夹里面的YRouterNavigationController.swift拖到你的工程里面,就可以使用了,载配合上一个自定义的BaseVC,简直是VC跳转最舒服的方式。源码很简单,看看应该就能理解。
轮播图
轮播图,这个确实懒得去找并且评估比较好的开源项目了,逻辑也非常简单。就自己动手造了一个。YRouterSwiftDemo
YRouterSwiftDemo支持代码和xib的初始化,支持block和delegate的回调方式。简便易用,文件被存储在了沙盒的/Caches/NetImagesCache/文件夹内,可以配合我的修改版Kingfisher使用,清理图片缓存的时候就可以直接调用Kingfisher的方法了。😄
简单的说一这个轮播图的实现原理吧:scrollView的contentsize为三倍其本身大小,currentImageView始终位于其中部,左滑就把otherImageView放到右边,滑动完成,重新设置currentImageView的图片并修改scrollView.contentOffset使之重新回到展示currentImageView的位置,向右滑动也是同样的道理。这样就能无限的循环了。大体原理就是这样,两个imageView,三倍本身控件宽度的contentSize的scrollView,就可以无限的滑动了。剩下的就是一些细节的调整了,具体可以去看看源代码。
搜索框
还未整理,等待日后填坑😄
最近搜索或推荐控件
还未整理,等待日后填坑😄
经过这个Swift项目,我感觉我已经喜欢上Swift的简洁语法,闭包等特性,写出的代码比OC还要优雅,以后能用Swfit的项目肯定会用了。
PS:因为之前的时候我自己私有的代码仓库都放在了coding上了,但是大约在4月份的时候发了通知说6月份开始普通用户的私有仓库只能有2个了,并且每个仓库的容量被限制在了128MB,纳尼?我之前所有的私有和公开的代码都在上面啊,然后看了一下,199RMB/年的账户也只能100个私有仓库,所以决定,以后会慢慢的把私有仓库迁移到码云上,然后公开的放在GitHub上。