引子:
手中維護(hù)了一個歷史項目,該項目因為歷史原因,從設(shè)計到實現(xiàn),并不是很好.加之該項目為支線項目,在得到了老大的批準(zhǔn)后,它不幸的被我作為了試驗田...
為此,我重新開啟了一個工程,引入了AOP,MVVM,Swift等.僅僅是初體驗,并沒有特別高深的應(yīng)用以及所謂的"最佳實踐".
混編:
項目仍然以O(shè)C為主,用來編寫大量的UI代碼,原因為:一則對Swift掌握程度不如OC,二則UI代碼使得Swift無法發(fā)揮其優(yōu)勢,三則擔(dān)心Swift版本變動.
我選擇Swift作為邏輯的處理.所以首先需要做混編的支持.
在工程中新建一個Swift文件,工程會自動詢問你(僅詢問一次)是否建立一個bridge文件,選擇是,則會出現(xiàn)一個名為XXX(工程名)-Bridging-Header.h的文件
這個文件主要用于OC->Swift.即在該h文件中import的類,Swift均可以自由調(diào)用.在Build Settings中輸入Bridging進(jìn)行搜索,可以看到有一個屬性叫做
Objective-C Bridging Header,在這里可以設(shè)置XXX-Bridging-Header.h文件的路徑.
通過設(shè)置,我們可以在Swift里面調(diào)用OC的相關(guān)代碼,但是我們的目標(biāo)并沒有實現(xiàn).我們希望使用Swift進(jìn)行運(yùn)算處理,將最終的結(jié)果返回給OC(UI)加以顯示.
那么我們還需要進(jìn)行Swift->OC的橋接.
編譯帶有Swift文件的項目后,項目會生成一個XXX(項目名)-swift.h的文件,我們只需要import這個文件,即可調(diào)用所有Swift的代碼.理所當(dāng)然,我將該文件
import到了PrefixHeader.h中.BTW,XCode6新項目已經(jīng)不會初始化一個PrefixHeader文件了,需要我們手工創(chuàng)立.
到現(xiàn)在為止,我們既可以在Swift中調(diào)用OC,也可以在OC中調(diào)用Swift了.
起飛:
準(zhǔn)備工作做好了以后,就開始享受Swift帶來的快感了.
- 它沒有mutable,只有var和let
- 它有強(qiáng)大的?和!,不過上手挺有難度
- 它有泛型,也同樣類似OC一般,擁有Any和AnyObject
- 它有元組,終于可以像紅寶石一樣寫出類似于(a,b) = (b,a)的代碼了.
- 它有強(qiáng)大的struct,強(qiáng)大的switch
- 它有簡潔的closure,c like的block見鬼去吧...
- 他還有更加強(qiáng)大的func以及奇奇怪怪的小東西,什么柯里化拉等等.
我用它實現(xiàn)大部分的M和VM,小部分的V,其樂無窮.例如:
正則(自定義/重載操作符):
infix operator =~{
}
func =~(lhs: String,rhs: String) -> Bool{
let regex: NSRegularExpression = NSRegularExpression(pattern: rhs, options: NSRegularExpressionOptions.CaseInsensitive, error: nil)!
let range: NSRange = regex.rangeOfFirstMatchInString(lhs, options: NSMatchingOptions.ReportProgress, range: NSMakeRange(0, count(lhs)))
return range.length > 0
}
更強(qiáng)大的enum
enum SWButtonImageLoadingStatus{
case Success(UIImage)
case Failure(NSError?)
}
class SWImageSelectorButton: UIButton {
var url: String = ""
func loadButtonImage(url: String,handler : (status: SWButtonImageLoadingStatus) -> ()){
SWTemplateCenter.sharedInstance().runAction("getImage", params: params, success: {
(data) -> Void in
if let image = UIImage(data: data as! NSData){
let status = SWButtonImageLoadingStatus.Success(image)
handler(status: status)
}
else{
let status = SWButtonImageLoadingStatus.Failure(nil)
handler(status: status)
}
}) {
(error) -> Void in
let status = SWButtonImageLoadingStatus.Failure(error)
handler(status: status)
}
}
}
坑:
天下哪有不停的爽點.坑當(dāng)然有.
混編機(jī)制導(dǎo)致了他們的通信依賴2個文件:XXX-swift.h和XXX-Bridging-Header.h.隨著交互的越深,XXX-Bridging-Header.h文件中所引入的頭文件
會爆炸,難以管理,很是丑陋.有時候為了實現(xiàn)一個小功能,要不然引入OC的類作為全局引用,要不然自行重寫一遍.那么此時,我的選擇是...還是使用OC吧...
Swift版本變動是一個深坑.Swift還太年輕,版本變動會非常劇烈.而每一次版本變動,帶來的直接結(jié)果就是大量的編譯錯誤.需要重新修改代碼.盡管Apple會
提供遷移工具,但是,這并沒有什么用.人工檢查和修改是一定套不了的.Swift2.0發(fā)布在即,變的更成熟,更科學(xué),更美好.而我,也到時候會迎來一次全面的檢查
和修復(fù),痛并快樂著.
在混編的過程中,有部分Swift的威力無法發(fā)揮.比如方法中無法定義參數(shù)的var,inout等,因為這樣的話無法翻譯成OC.這當(dāng)然不算Swift的坑,不過也蠻遺憾的.
iOS8以下并未含有Swift庫,所以使用Swift后會把Swift相關(guān)庫也打成包并入App中.由此帶來的問題是:即使你只寫了一行Swift代碼,App也會增大8m左右,
不過新版本的iOS已經(jīng)解決.
在實際應(yīng)用中,我曾經(jīng)出現(xiàn)過偶爾的Swift調(diào)用UIKit的錯誤:同樣的代碼,得出的結(jié)果就是不一樣.換成OC重寫一遍就OK了(在做轉(zhuǎn)場動畫,實現(xiàn)UIViewControllerAnimatedTransitioning協(xié)議的時候).我雖然認(rèn)為這應(yīng)該是我對Swift了解不足的原因,但是Swift還是給我造成了一定的困惑.
結(jié)語:
Swift具備先進(jìn)的語法,現(xiàn)代化語言的特征,蘋果爸爸的運(yùn)營,相信有著非常光明的前途.加之2.0即將到來并開源,一反蘋果封閉的常態(tài),野心也是極大的.目前使用Swift開發(fā)項目,雖然有一定的風(fēng)險,有版本變動帶來的額外工作量,但是跟隨一門語言的演化,也算是值了.