標籤:http 檔案 os for io 問題
好吧,能找到這文章的,一般是接到了如下需求:
我是從raywenderlich抽了點內容出來做日記,另外,本文說的不是布局的適配,而是因為ios的升級帶來的各版本代碼上的不相容。
Deployment Target vs. Base SDK
總的來說,Base SDK表示你願意支援的最高版本,位於你要設定的Target的屬性頁面的Build Settings > Architectures,一般就選擇Latest iOS即可,比如我寫這篇日誌的時候已經是8.0了
而Deployment Target則表示了你願意支援的最低版本,位於同樣的Build Setting下的Deployment一節裡面,你可以找到iOS Deployment Target
發現相容問題
這個簡單:
運行老舊系統的真機
你有那麼多機器的話
運行模擬器
你有裝那麼多SDK的話,當然這個也不是不可能啦
蘋果的文檔
Header Files
原文如下,但是我真沒發現Command-click後跳轉的有 NS_AVAILABLE_IOS() and NS_CLASS_AVAILABLE_IOS()這兩個宏,這不能說明就沒有相容性問題吧?。。。
Sometimes the best documentation of methods and classes is contained right in the source code.
Simply Command-click the symbol you want to inspect, and Xcode will take you to its header file, where you will find the information you need along with the parameters of the preprocessor macros NS_AVAILABLE_IOS() and NS_CLASS_AVAILABLE_IOS(). If a class or method declaration doesn’t use either of those availability macros, you can assume that they won’t cause any compatibility issues.
Note: ALT + click on a method will display a popover that contains these same details along with other information about the method.
蘋果提供的Apid Diffs
這個應該是最全的了
https://developer.apple.com/library/ios/releasenotes/General/iOS60APIDiffs/
https://developer.apple.com/library/ios/releasenotes/General/iOS70APIDiffs/
依次類推,
當然預覽狀態的就是如下了:
https://developer.apple.com/library/prerelease/ios/releasenotes/General/iOS80APIDiffs/
Deploymate
這是一個付費服務,簡單來說,花錢外包了。油條幫上的示範視頻deploymate,自行翻牆
MJGAvailability
一個樣本標頭檔,來自MJGFoundation,會欺騙編譯器某些api已經deprecated了,從而觸發警告,用法在檔案頭已經說得很清楚了,自己可以試試。
解決相容問題
新版本會引入新的架構、類、方法、常量以及枚舉,分別如下
frameworks
在Build Phases -> Link Binary With Libraries,將特定架構從Required改為Optional,這將會weak link你選定的架構
classes
目標版本可能不支援的類,文章提供的是iOS4.2的寫法,嚴重懷疑現在有了新的寫法,或者已經不支援了,希望有人留個言:
if ([SLComposeViewController class]) { //Safe to use SLComposeViewController } else { //Fail gracefully}
methods
if ([self.image respondsToSelector:@selector(resizableImageWithCapInsets:resizingMode:)]) { //Safe to use this way of creating resizable images} else { //Fail gracefully}
如果是類方法,用類而不是執行個體即可:
if ([UIView respondsToSelector:@selector(requiresConstraintBasedLayout)]) { //Safe to use this method} else { //Fail gracefully}
同樣的方法可以探測類是否支援某個屬性,比如UILabel是否有attributedText,可以用@selector(setAttributedText)
constants/C functions
一般表現為extern NSString *或C語言的方法,比如一個iOS6引入的c方法ABAddressBookCreateWithOptions(...),在iOS5中想不掛掉可以這麼判斷:
if (ABAddressBookCreateWithOptions != NULL) { //Safe to use}else { //Fail gracefully}
常量也一樣:
if (&UIApplicationWillEnterForegroundNotification) { //Safe to assume multitasking support}else { //Fail gracefully}
enumeration values
請看原文
Checking for the existence of enumeration or bit mask values — the kind that you would find inside an NS_ENUM or NS_OPTIONS declaration — is incredibly difficult to check at runtime. Why?
Under the hood, an enumeration is just a method of giving names to numeric constants. An enum is replaced with an int when compiled, which always exists!
If you’re faced with the situation of needing to see if a certain enumeration exists, all you can do is either explicitly check the OS version (which isn’t recommended) or alternatively check against another API element that was introduced at the same time as the new enumeration value.
Note: Whichever way you do this, be sure to add adequate comments to any such code and consider wrapping the code in a dedicated compatibility helper.
顯式版本檢測
NSString *osVersion = [[UIDevice currentDevice] systemVersion];, 但作者不推薦。。。
最後,水果官方的相容性指南:SDK Compatibility Guide