最近公司新開了一個項目,由於我的同事的離職,所以就剩我自己了。於是就果斷的使用純純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上。