昨晚上一波手賤把我的小5s升到iOS10。如此配套的話,Xcode7.3升級Xcode8.1看來也是勢在必行了。公司程序是Swift2.3的,出於對蘋果的恐懼遲遲不敢升級。但丑媳婦兒總要見公婆,借這個機會,也趁雙休時間,做一下適配好了。
首先,強調一點。做好備份!做好備份!做好備份!重要的事情說三遍。
1.關於使用的Swift代碼庫的問題
這是我最心力交瘁的一個問題。
項目中使用了Swift的幾個開源框架,SwiftHTTP、SwiftyJSON、KingFisher等等。我的項目並沒有使用CocoaPods,是直接將源碼放到工程里面的。但很明顯,這些三方框架也依然是Swift2.3時代的產物。首先,不管是用CocoaPods還是直接拷貝源文件的方式,請將你的三方框架升級到支持Swift3.0的版本(假如有的話),最好是最新版本。
我是直接到GitHub上下載源文件,直接替換后,刪掉原來導入的框架,然后重新導入框架的。
接下來,打開工程,它會這樣提示你:
點擊Convert后:
第一次我,天真的以為我選擇"Later"->"Later"我就什么都不用改就可以運行我的程序,或者說,點擊Convert后選擇Swift2.3可以實現直接跑程序。事實證明,仍然有兩百個紅色錯誤等着你去修改。我為什么不直接弄到Swift3.0呢?這樣,我毅然決然刪了第一份選擇"Later"->"Later"和第二份選擇"Convert"->"Swift2.3"的兩份程序,開始實現Swift3.0之旅。
假如之前更新你的三方框架的過程一切順利的話,這里應該只有你的源程序,也就是XXX.app需要選擇;如果非常不巧你的支持庫里面並不支持Swift3.0,苦逼吧那就,不但需要在這里也選上,而且也需要在接下來三方框架的各種報錯中苦苦掙扎。我相信你們的實力,恩。
接下來是漫長的等待。
等待過后,只有一個藍色的Save可選。我不多說,自己理解
以上這幾條步驟,足足花了我一個半小時,但這只是萬里長征的第一步。
接下來,你可能遇到這樣的問題:
[報錯信息] “Use Legacy Swift Language Version” (SWIFT_VERSION) is required to be configured correctly for targets which use Swift. Use the [Edit > Convert > To Current Swift Syntax…] menu to choose a Swift version or use the Build Settings editor to configure the build setting directly.
[解決方案] 設置 Build Settings —-> Use Legacy Swift Language Version —-> YES/NO,改為NO或者YES。
沒錯,你沒有看錯,就是這么任性。有人說選擇YES,有人說選擇NO;依我的作法看,每一個都試試才是王道。。
其他的許多問題,通常在你更新框架后即可解決。不再贅述。
另外再說一句,紅圈的警告,回車即好,接下來重點解決出現的各種紅感嘆號警告。
2.Value of type 'UIImageView' has no member 'kf_setImageWithURL'
報錯代碼:
1 repairImageView.kf_setImageWithURL(URL.init(string: self.repairDetail!.img!)!, placeholderImage: UIImage.init(named: "tp"), optionsInfo: nil, progressBlock: nil, completionHandler: { (image, error, cacheType, imageURL) in 2 3 self.image = image 4 })
很明顯是KingFisher的三方庫中出現的問題。UIImageView類型沒有"kf_setImageWithURL"這個成員,也就是屬性與方法。那就是這個方法替換掉了。我們找一下其他的方式。
最終解決方案:使用這個方法解決:
1 repairImageView.kf.setImage(with: URL.init(string: self.repairDetail!.img!)!, placeholder: UIImage.init(named: "tp"), options: nil, progressBlock: nil, completionHandler: { (image, error, cacheType, imageURL) in 2 3 self.image = image 4 })
猛然發現自己說了太多廢話。其實就是替換掉了這些內容: kf_setImageWithURL( -> kf.setImage(with:
就這樣子。方法名換了。
3.“ambiguous referenc to member datask(with: completionhandler:)”
報錯代碼:
1 let task: URLSessionDataTask = session.dataTask(with: request) { (data, resp, err) in }
莫名其妙就報錯了。其實解決方案很簡單,是因為:
1 let request = NSMutableURLRequest(url:myUrl!);
即:request是NSMutableURLRequest類型的,但是參數要求為URLRequest類型。所以代碼改成這樣即可:
1 let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) in
request as URLRequest 強制轉換類型。
4.Argument labels '(_:)' do not match any available overloads
報錯代碼:
1 let common = Mapper<Common>().map(ts)!
其中:Common是遵守了Mappable的模型類,ts是個字符串。這很明顯是在使用ObjectMapper時,方法名替換了。
解決方案:
1 let common = Mapper<Common>().map(JSONString: ts)
ps:之前Swift的方法在使用中第一個參數的形參被省略,我是很看不慣這一點。不過貌似蘋果又給改回來了,五星好評!
pps:突然又想起來賊難用的快捷注釋以及賊賊難看的字體。一星不謝。
5.Type 'Any' has no subscript members
這一條簡直莫名其妙。大體意思就是,你這個類型"Any"不是個數組或者字典,不能按照下標取東西。
我之前通過一個方法默認創建了一個字典,編譯器也認為這是個字典,所以允許我取東西,但是現在編譯器翻臉了,說你必須告訴我這是個字典我才能讓你取東西。okok。
1 (dic as! NSDictionary)
同理還有各種類型不匹配的問題,強制轉換就可以了。(偷偷說,真懷念OC的弱類型的時代~)