一個才適應Swift2.2的開發者眼中的Swift 3.0和iOS 10

食用指南

Xcode 8帶着Swift 3風風火火的到來了,做爲一個平時使用OC爲主的iOS開發來講,Swift 3正式和OC-like語法劃定了界限。您能夠簡單瀏覽本文,也能夠把本文當作從Swift2.2遷移到Swift3的指南。若是您在遷移的過程當中遇到了問題,不妨直接CTRL+F來搜索一下本文,看能不能找到解決方法。
由於本文是做爲公司的內部培訓資料,因此若是您在閱讀的時候發現了錯誤或者是有更好的解決方法,歡迎聯繫我或者在下方留下您的評論。git

1.蘋果官方提供的Swift 3 更新內容(部分Objective-C語法也變動了)

1.1 語法上的形式變動

語法形式上的變動是很是方便理解的,在遷移過程當中,Xcode會自動提示您轉爲對應的格式,形式變動的內容以下:github

  • 系統提供的枚舉類型默認轉爲小寫 好比 UIButton(type: .Custom) -> UIButton(type: .custom)web

  • 類型判斷語法變化 object.dynamicType -> type(of: object)數據庫

  • UIViewController.statusBarStyle -> -(UIStatusBarStyle)preferredStatusBarStyle{}swift

  • Core Graphics API Swift化,基原本說這一部分能自動化就自動化轉換,量太大了...api

  • webview的代理方法- (void)webView:(UIWebView *)webView didFailLoadWithError:(nullable NSError *)error須要去掉nullable不然會報錯安全

1.2 逃逸閉包必須顯示聲明

如今swift3.0全部的函數都是默認@noescape 非逃逸閉包,而 逃逸閉包(閉包在函數調用完以後才被調用的)必須顯示聲明@escaping,好比:ruby

func transport(requestMethod: Alamofire.HTTPMethod, url: String, callback: @escaping (Any) -> Void) -> Void {}

1.3 typealias 支持泛型

這帶來了什麼?更加抽象的CollectionType,甚至是更加便捷的JSON轉模型方法網絡

1.4 selector支持屬性的getter和setter方法

class Dog {
    var dogName: String
}

let dogNameGetter = #selector(getter: Dog.dogName)

1.5 Dispatch徹底拋棄C-like 寫法

是的,您的Snippet應該更新一下了!大部分舊寫法都能找到新的寫法替換,不過對於dispatch_once來講就徹底被廢棄,您可使用 懶加載 來替代。閉包

DispatchQueue.global().async {
    // 異步操做
    DispatchQueue.main.async {
        // 主線程操做
    }
}

DispatchQueue.global().sync {
    // 同步操做
}

//建立隊列
let serialQueue = DispatchQueue(label: "Queuename")

//延遲執行
let delay = DispatchTime.now() + DispatchTimeInterval.seconds(\Seconds)
DispatchQueue.main.asyncAfter(deadline: delay) { 
}

1.6引入系統版本判斷代碼

if #available(iOS 10.0,*){
    //您的代碼
}

1.7Any類型會逐漸開始使用

在Swift2的項目中,可能使用AnyObject更加頻繁,由於在Swift2 中編譯器默認作了基本類型到OC類型的橋接。在Swift3中,這類橋接被廢棄,因此須要明確Any和AnyObject的區別,也就是Any包含AnyObjectAny類型包括struct、class、selector等,而AnyObject只對應class

2. iOS 10給遷移帶來的其餘須要注意點

2.1 2017年1月1日以前強制使用HTTPS

在iOS9中默認HTTP是被禁止的,能夠在info.plist中經過設置NSAllowsArbitraryLoadsYES打開。新iOS 10若是要訪問網絡也能夠如iOS 9 同樣設置來訪問網絡,可是這在2017年1月1日以後有可能會被拒絕,您能夠經過NSExceptionDomains來針對特定域名開放HTTP訪問。

2.2 隱私權限更嚴格了

iOS 10開始約束隱私權限了,若是您用到 相冊、相機、位置、藍牙、提醒事項、運動健康數據、麥克風、日曆 等狀況,您須要手動在info.plist中添加權限請求說明。不然很大概率會閃退,This app has crashed because it attempted to access privacy-sensitive data without a usage description.
添加的字段名以下圖所示:

2.3 默認不提供網絡訪問權限

iOS 10默認不提供網絡訪問,也就是說,剛剛進入應用,在用戶沒有點擊「贊成App訪問蜂窩數據」以前是沒法訪問網絡的。即便在用戶點擊確認以後,App每每沒有設置自動刷新,用戶體驗不好的,但願您能注意一下。

2.4 字體變大,低版本顯示正常的Label在iOS10中變成「...」

iOS10使用了新字體,文字的寬度變大了,以前若是是UILabel寫死寬度或者定死寬度約束的極可能就會出現文字變成「...」,須要手動處理一下。UILabel大部分時候只須要給一個Origin Point就夠了,文字的大小實際上不須要寫死的。

2.5 推送須要明確打開Capability

在XCode7中這裏的開關不打開,推送也是能夠正常使用的,可是在XCode8中,這裏的開關必需要打開,否則會報錯

Error Domain=NSCocoaErrorDomain Code=3000 "未找到應用程序的「aps-environment」的受權字符串" UserInfo={NSLocalizedDescription=未找到應用程序的「aps-environment」的受權字符串}
打開後會在本地生成entitlements文件

3. Xcode 8給咱們帶來了哪些便利和麻煩

3.1 Xcode 8內置的Swift遷移工具

總的來講,此次遷移工具幫了很大的忙。若是您打開一個Swift 2工程,遷移會主動提示您打開了一個Swift 的舊工程,問您是否是要自動進行語法轉換。本人建議您進行手工遷移,反正我是歷來沒有一次性遷移成功過的。手動遷移也沒有特別麻煩,遷移工具在局部的語法提示會快速幫您定位須要遷移的位置。在我看來,自動遷移提示存在的目的在於幫您檢測了集成的第三方庫是否是也是用Swift 3語法寫的。

3.2 Xcode 8徹底不支持舊有的插件了

是的,徹底不支持了,也再也不支持Alcatraz提供的插件,VVDocumenter、FuzzyAutocomplete、cocoapods-plugin 手動再見~~ Xcode官方的說法是爲了安全考慮。的確,瘋狂裝插件在崩潰的時候要找到出問題的插件仍是要花費一番功夫的。並且Xcode如今能夠方便的開發編輯器插件了,只不過這些新插件的功能真心太弱了,太弱了...是的,我指的是,在座的各位新插件都是弱雞。目前的解決辦法是對Xcode進行重簽名,而後生成一個「越獄版」的Xcode放在應用程序目錄,教程連接地址在此。或者要不咱們仍是繼續用Xcode 7.3.1吧...反正我是戒掉插件了。

3.3 Swift 2.3的使用

Xcode 7.3.1 是Swift 2.2 版本,而Xcode新建的工程默認都是基於Swift 3.0 的,若是您的工程是基於Swift2.3的版本的,您須要在Xcode 8.0 的 Build Settings - Use Legacy Swift Language Version中將參數的值設爲Yes,不過須要注意的是,若是是用Swift2.3的工程,第三方的工程也須要爲Swift 2.3的版本,在您創建工程的時候,您應該提前肯定您使用的第三方庫是否支持Swift 2.3 。

3.4 Xcode 8如今支持圖片文件名補全

Xcode 8如今支持圖片文件名補全,在您鍵入UIImage(named: "ImageName")的時候會自動提示您工程中的圖片,固然您也能夠直接鍵入圖片名稱,即UIImage(named: "ImageName") -> ImageName, Xcode會在圖片名稱的前面創建一個小的縮略圖,真的很小。

3.5 Xcode 8須要開啓註釋

若是遇到按CTRL + /註釋沒有效果了,那能夠在終端裏敲上~ sudo /usr/libexec/xpccachectl,而後重啓電腦試試。

3.6 Xcode 8瘋狂打印一大堆Log

在工程Edit Scheme中添加參數,以下圖所示:

3.7 Xcode代碼簽名優化

總的來講是蘋果幫您把簽名管理起來了,就是通常不會出現Fix issue的黃色小三角形了,沒有特別須要咱們作的。

3.8 舊版本的Xcode沒法打開Xcode 8保存過的storyboard和xib了

由於新的Interface Builder添加了初始化界面的功能,默認打開舊有的storyboard和xib會詢問您是否將全部視圖設定爲一個統一的尺寸,若是您點擊確認,只須要更新一下frame就能夠看到結果,可是這在團隊協做中會帶來一個問題,在版本管理中,一旦push代碼以後,團隊中使用Xcode 8如下的成員就沒法打開新版本的storyboard和xib了,解決方法是在Source Code層面打開storyboard或者xib,手動刪除<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>便可。

3.9 在Xcode中使用相似VVdocument的功能

快捷鍵:option + command + /

3.10 你能夠每7天建立10個APP IDs

每一個階段能建立的App ID數量會有限制,你能夠每7天建立10個APP IDs

4. 一些小的注意點

4.1 Cocoapod仍是主力的包管理工具

可能您據說過SPM(Swift Package Manager),這個相似NPM的包管理工具在很早官方就發佈消息說要支持了,可是實際應用中,不少第三方庫目前並不支持(至少從目前來看),工具的使用遠遠沒有Yarn之於NPM那樣的平滑遷移,因此目前仍是建議使用Cocoapod或者是Carthage吧!

4.2 RealmSwift 在Swift 3.0上要求進行數據庫升級

準確的說,是當您將RealmSwift升級到3.0能支持的版本以後,在操做數據庫的時候要求您升級數據庫。因此仍是一步到位升級到3.0吧,別在2.3再折騰一遍了。

4.3 Alamofire 3.0再也不支持iOS 8

反正我放個圖:

4.4 Cocoapods 中強制使用 Swift 3 語法

只須要在Podfile中添加:

#swift 3 adapt
post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['SWIFT_VERSION'] = '3.0'
    end
  end
end

4.5 獲取特定branch、tag、倉庫的第三方庫

在剛剛開始適配Swift 3的階段,會遇到至關多的問題,好比:

  • 做者尚未到Cocoapods官方設置更新信息

  • 做者將Swift 3的版本創建在其餘分支上,默認支持的仍是2.2或者是2.3的版本。

  • 做者根本尚未支持Swift 3 ,不過有熱心的網友建了一個本身的倉庫,幫忙適配了一下

這時候您能夠嘗試在pod後面添加一些描述信息來定位到您真正想要獲取到的庫的位置,好比這裏就把SwiftyJSON庫的獲取地址轉到了IBM維護的一個倉庫上:

pod 'SwiftyJSON',
  :git => 'https://github.com/IBM-Swift/SwiftyJSON.git',
  :branch => 'master'
相關文章
相關標籤/搜索