iOS 10 的適配問題

原文鏈接:http://www.lxweimin.com/p/f8151d556930

隨著iOS10發布的臨近,大家的App都需要適配iOS10,下面是我總結的一些關于iOS10適配方面的問題,如果有錯誤,歡迎指出.

1.系統判斷方法失效:

在你的項目中,當需要判斷系統版本的話,不要使用下面的方法:

#define isiOS10 ([[[[UIDevice currentDevice] systemVersion] substringToIndex:1] intValue]>=10)

它會永遠返回NO,substringToIndex:1在iOS 10 會被檢測成 iOS 1了,

應該使用下面的這些方法:

Objective-C 中這樣寫:

#define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)

#define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)

#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)

#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

或者使用:

if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){.majorVersion = 9, .minorVersion = 1, .patchVersion = 0}]) { NSLog(@"Hello from > iOS 9.1");}

if ([NSProcessInfo.processInfo isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){9,3,0}]) { NSLog(@"Hello from > iOS 9.3");}

或者使用:

if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_9_0) { // do stuff for iOS 9 and newer} else { // do stuff for older versions than iOS 9}

有時候會缺少一些常量,NSFoundationVersionNumber是在NSObjCRuntime.h中定義的,作為Xcode7.3.1的一部分,我們設定常熟范圍從iPhone OS 2到#define NSFoundationVersionNumber_iOS_8_4 1144.17,在iOS 10(Xcode 8)中,蘋果補充了缺少的數字,設置有未來的版本.

#define NSFoundationVersionNumber_iOS_9_0 1240.1

#define NSFoundationVersionNumber_iOS_9_1 1241.14

#define NSFoundationVersionNumber_iOS_9_2 1242.12

#define NSFoundationVersionNumber_iOS_9_3 1242.12

#define NSFoundationVersionNumber_iOS_9_4 1280.25

#define NSFoundationVersionNumber_iOS_9_x_Max 1299

Swift中這樣寫:

if NSProcessInfo().isOperatingSystemAtLeastVersion(NSOperatingSystemVersion(majorVersion: 10, minorVersion: 0, patchVersion: 0)) {

// 代碼塊

}

或者使用

if #available(iOS 10.0, *) {

// 代碼塊

} else {

// 代碼塊

}

2.隱私數據訪問問題:

你的項目中訪問了隱私數據,比如:相機,相冊,聯系人等,在Xcode8中打開編譯的話,統統會crash,控制臺會輸出下面這樣的日志:

這是因為iOS對用戶的安全和隱私的增強,在申請很多私有權限的時候都需要添加描述,但是,在使用Xcode 8之前的Xcode還是使用系統的權限通知框.

要想解決這個問題,只需要在info.plist添加NSContactsUsageDescription的key, value自己隨意填寫就可以,這里列舉出對應的key(Source Code模式下):


NSPhotoLibraryUsageDescription

App需要您的同意,才能訪問相冊


NSCameraUsageDescription

App需要您的同意,才能訪問相機


NSMicrophoneUsageDescription

App需要您的同意,才能訪問麥克風


NSLocationUsageDescription

App需要您的同意,才能訪問位置


NSLocationWhenInUseUsageDescription

App需要您的同意,才能在使用期間訪問位置


NSLocationAlwaysUsageDescription

App需要您的同意,才能始終訪問位置


NSCalendarsUsageDescription

App需要您的同意,才能訪問日歷


NSRemindersUsageDescription

App需要您的同意,才能訪問提醒事項


NSMotionUsageDescription App需要您的同意,才能訪問運動與健身


NSHealthUpdateUsageDescription

App需要您的同意,才能訪問健康更新


NSHealthShareUsageDescription

App需要您的同意,才能訪問健康分享


NSBluetoothPeripheralUsageDescription

App需要您的同意,才能訪問藍牙


NSAppleMusicUsageDescription

App需要您的同意,才能訪問媒體資料庫

如果不起作用,可以請求后臺權限,類似于這樣:

UIBackgroundModes


location

...

或者在Xcode里選中當前的target,選擇Capabilities,找到Background Modes,打開它,在里面選擇對應權限

3.UIColor的問題

官方文檔中說:大多數core開頭的圖形框架和AVFoundation都提高了對擴展像素和寬色域色彩空間的支持.通過圖形堆棧擴展這種方式比以往支持廣色域的顯示設備更加容易。現在對UIKit擴展可以在sRGB的色彩空間下工作,性能更好,也可以在更廣泛的色域來搭配sRGB顏色.如果你的項目中是通過低級別的api自己實現圖形處理的,建議使用sRGB,也就是說在項目中使用了RGB轉化顏色的建議轉換為使用sRGB,在UIColor類中新增了兩個api:

- (UIColor *)initWithDisplayP3Red:(CGFloat)displayP3Red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha NS_AVAILABLE_IOS(10_0);

+ (UIColor *)colorWithDisplayP3Red:(CGFloat)displayP3Red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha NS_AVAILABLE_IOS(10_0);

4.真彩色的顯示

真彩色的顯示會根據光感應器來自動的調節達到特定環境下顯示與性能的平衡效果,如果需要這個功能的話,可以在info.plist里配置(在Source Code模式下):

UIWhitePointAdaptivityStyle

它有五種取值,分別是:

UIWhitePointAdaptivityStyleStandard // 標準模式

UIWhitePointAdaptivityStyleReading // 閱讀模式

UIWhitePointAdaptivityStylePhoto // 圖片模式

UIWhitePointAdaptivityStyleVideo // 視頻模式

UIWhitePointAdaptivityStyleStandard // 游戲模式

也就是說如果你的項目是閱讀類的,就選擇UIWhitePointAdaptivityStyleReading這個模式,五種模式的顯示效果是從上往下遞減,也就是說如果你的項目是圖片處理類的,你選擇的是閱讀模式,給選擇太好的效果會影響性能.

5.ATS的問題

1.在iOS 9的時候,默認非HTTS的網絡是被禁止的,我們可以在info.plist文件中添加NSAppTransportSecurity字典,將NSAllowsArbitraryLoads設置為YES來禁用ATS;

2.從2017年1月1日起,,所有新提交的 app 默認不允許使用NSAllowsArbitraryLoads來繞過ATS的限制,默認情況下你的 app 可以訪問加密足夠強的(TLS V1.2以上)HTTPS內容;

3.可以選擇使用NSExceptionDomains設置白名單的方式對特定的域名開放HTTP內容來通過審核,比如說你的應用集成了第三方的登錄分享SDK,可以通過這種方式來做,下面以新浪SDK作為示范(Source Code 模式下):

NSAppTransportSecurity

NSExceptionDomains

sina.cn

NSThirdPartyExceptionMinimumTLSVersion

TLSv1.0

NSThirdPartyExceptionRequiresForwardSecrecy

NSIncludesSubdomains

weibo.cn

NSThirdPartyExceptionMinimumTLSVersion

TLSv1.0

NSThirdPartyExceptionRequiresForwardSecrecy

NSIncludesSubdomains

weibo. com

NSThirdPartyExceptionMinimumTLSVersion

TLSv1.0

NSThirdPartyExceptionRequiresForwardSecrecy

NSIncludesSubdomains

sinaimg.cn

NSThirdPartyExceptionMinimumTLSVersion

TLSv1.0

NSThirdPartyExceptionRequiresForwardSecrecy

NSIncludesSubdomains

sinajs.cn

NSThirdPartyExceptionMinimumTLSVersion

TLSv1.0

NSThirdPartyExceptionRequiresForwardSecrecy

NSIncludesSubdomains

sina.com.cn

NSThirdPartyExceptionMinimumTLSVersion

TLSv1.0

NSThirdPartyExceptionRequiresForwardSecrecy

NSIncludesSubdomains

4.在iOS 10 中info.plist文件新加入了NSAllowsArbitraryLoadsInWebContent鍵,允許任意web頁面加載,同時蘋果會用 ATS 來保護你的app;

5.安全傳輸不再支持SSLv3, 建議盡快停用SHA1和3DES算法;

6.UIStatusBar的問題:

在iOS10中,如果還使用以前設置UIStatusBar類型或者控制隱藏還是顯示的方法,會報警告,方法過期,如下圖:

上面方法到 iOS 10 不能使用了,要想修改UIStatusBar的樣式或者狀態使用下圖中所示的屬性或方法:

@property(nonatomic, readonly) UIStatusBarStyle preferredStatusBarStyle NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; // Defaults to UIStatusBarStyleDefault

@property(nonatomic, readonly) BOOL prefersStatusBarHidden NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; // Defaults to NO

- (UIStatusBarStyle)preferredStatusBarStyle NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; // Defaults to UIStatusBarStyleDefault

- (BOOL)prefersStatusBarHidden NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; // Defaults to NO

// Override to return the type of animation that should be used for status bar changes for this view controller. This currently only affects changes to prefersStatusBarHidden.

- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; // Defaults to UIStatusBarAnimationFade

7.UITextField

在iOS 10 中,UITextField新增了textContentType字段,是UITextContentType類型,它是一個枚舉,作用是可以指定輸入框的類型,以便系統可以分析出用戶的語義.是電話類型就建議一些電話,是地址類型就建議一些地址.可以在#import文件中,查看textContentType字段,有以下可以選擇的類型:

UIKIT_EXTERN UITextContentType const UITextContentTypeName ? ? ? ? ? ? ? ? ? ? ?NS_AVAILABLE_IOS(10_0);

UIKIT_EXTERN UITextContentType const UITextContentTypeNamePrefix ? ? ? ? ? ? ? ?NS_AVAILABLE_IOS(10_0);

UIKIT_EXTERN UITextContentType const UITextContentTypeGivenName ? ? ? ? ? ? ? ? NS_AVAILABLE_IOS(10_0);

UIKIT_EXTERN UITextContentType const UITextContentTypeMiddleName ? ? ? ? ? ? ? ?NS_AVAILABLE_IOS(10_0);

UIKIT_EXTERN UITextContentType const UITextContentTypeFamilyName ? ? ? ? ? ? ? ?NS_AVAILABLE_IOS(10_0);

UIKIT_EXTERN UITextContentType const UITextContentTypeNameSuffix ? ? ? ? ? ? ? ?NS_AVAILABLE_IOS(10_0);

UIKIT_EXTERN UITextContentType const UITextContentTypeNickname ? ? ? ? ? ? ? ? ?NS_AVAILABLE_IOS(10_0);

UIKIT_EXTERN UITextContentType const UITextContentTypeJobTitle ? ? ? ? ? ? ? ? ?NS_AVAILABLE_IOS(10_0);

UIKIT_EXTERN UITextContentType const UITextContentTypeOrganizationName ? ? ? ? ?NS_AVAILABLE_IOS(10_0);

UIKIT_EXTERN UITextContentType const UITextContentTypeLocation ? ? ? ? ? ? ? ? ?NS_AVAILABLE_IOS(10_0);

UIKIT_EXTERN UITextContentType const UITextContentTypeFullStreetAddress ? ? ? ? NS_AVAILABLE_IOS(10_0);

UIKIT_EXTERN UITextContentType const UITextContentTypeStreetAddressLine1 ? ? ? ?NS_AVAILABLE_IOS(10_0);

UIKIT_EXTERN UITextContentType const UITextContentTypeStreetAddressLine2 ? ? ? ?NS_AVAILABLE_IOS(10_0);

UIKIT_EXTERN UITextContentType const UITextContentTypeAddressCity ? ? ? ? ? ? ? NS_AVAILABLE_IOS(10_0);

UIKIT_EXTERN UITextContentType const UITextContentTypeAddressState ? ? ? ? ? ? ?NS_AVAILABLE_IOS(10_0);

UIKIT_EXTERN UITextContentType const UITextContentTypeAddressCityAndState ? ? ? NS_AVAILABLE_IOS(10_0);

UIKIT_EXTERN UITextContentType const UITextContentTypeSublocality ? ? ? ? ? ? ? NS_AVAILABLE_IOS(10_0);

UIKIT_EXTERN UITextContentType const UITextContentTypeCountryName ? ? ? ? ? ? ? NS_AVAILABLE_IOS(10_0);

UIKIT_EXTERN UITextContentType const UITextContentTypePostalCode ? ? ? ? ? ? ? ?NS_AVAILABLE_IOS(10_0);

UIKIT_EXTERN UITextContentType const UITextContentTypeTelephoneNumber ? ? ? ? ? NS_AVAILABLE_IOS(10_0);

UIKIT_EXTERN UITextContentType const UITextContentTypeEmailAddress ? ? ? ? ? ? ?NS_AVAILABLE_IOS(10_0);

UIKIT_EXTERN UITextContentType const UITextContentTypeURL ? ? ? ? ? ? ? ? ? ? ? NS_AVAILABLE_IOS(10_0);

UIKIT_EXTERN UITextContentType const UITextContentTypeCreditCardNumber ? ? ? ? ?NS_AVAILABLE_IOS(10_0);

8.UserNotifications(用戶通知)

iOS 10 中將通知相關的 API 都統一了,在此基礎上很多用戶定義的通知,并且可以捕捉到各個通知狀態的回調.以前通知的概念是:大家想接受的提前做好準備,然后一下全兩分發,沒收到也不管了,也不關心發送者,現在的用戶通知做成了類似于網絡請求,先發一個request得到response的流程,還封裝了error,可以在各個狀態的方法中做一些額外的操作,并且能獲得一些字段,比如發送者之類的.這個功能的頭文件是:#import



9.UICollectionViewCell的的優化

在iOS 10 之前,UICollectionView上面如果有大量cell,當用戶活動很快的時候,整個UICollectionView的卡頓會很明顯,為什么會造成這樣的問題,這里涉及到了iOS 系統的重用機制,當cell準備加載進屏幕的時候,整個cell都已經加載完成,等待在屏幕外面了,也就是整整一行cell都已經加載完畢,這就是造成卡頓的主要原因,專業術語叫做:掉幀.

要想讓用戶感覺不到卡頓,我們的app必須幀率達到60幀/秒,也就是說每幀16毫秒要刷新一次.

iOS 10 之前UICollectionViewCell的生命周期是這樣的:

1.用戶滑動屏幕,屏幕外有一個cell準備加載進來,把cell從reusr隊列拿出來,然后調用prepareForReuse方法,在這個方法里面,可以重置cell的狀態,加載新的數據;

2.繼續滑動,就會調用cellForItemAtIndexPath方法,在這個方法里面給cell賦值模型,然后返回給系統;

3.當cell馬上進去屏幕的時候,就會調用willDisplayCell方法,在這個方法里面我們還可以修改cell,為進入屏幕做最后的準備工作;

4.執行完willDisplayCell方法后,cell就進去屏幕了.當cell完全離開屏幕以后,會調用didEndDisplayingCell方法.

iOS 10 UICollectionViewCell的生命周期是這樣的:

1.用戶滑動屏幕,屏幕外有一個cell準備加載進來,把cell從reusr隊列拿出來,然后調用prepareForReuse方法,在這里當cell還沒有進去屏幕的時候,就已經提前調用這個方法了,對比之前的區別是之前是cell的上邊緣馬上進去屏幕的時候就會調用該方法,而iOS 10 提前到cell還在屏幕外面的時候就調用;

2.在cellForItemAtIndexPath中創建cell,填充數據,刷新狀態等操作,相比于之前也提前了;

3.用戶繼續滑動的話,當cell馬上就需要顯示的時候我們再調用willDisplayCell方法,原則就是:何時需要顯示,何時再去調用willDisplayCell方法;

4.當cell完全離開屏幕以后,會調用didEndDisplayingCell方法,跟之前一樣,cell會進入重用隊列.

在iOS 10 之前,cell只能從重用隊列里面取出,再走一遍生命周期,并調用cellForItemAtIndexPath創建或者生成一個cell.

在iOS 10 中,系統會cell保存一段時間,也就是說當用戶把cell滑出屏幕以后,如果又滑動回來,cell不用再走一遍生命周期了,只需要調用willDisplayCell方法就可以重新出現在屏幕中了.

iOS 10 中,系統是一個一個加載cell的,二以前是一行一行加載的,這樣就可以提升很多性能;

iOS 10 新增加的Pre-Fetching預加載

這個是為了降低UICollectionViewCell在加載的時候所花費的時間,在 iOS 10 中,除了數據源協議和代理協議外,新增加了一個UICollectionViewDataSourcePrefetching協議,這個協議里面定義了兩個方法:

- (void)collectionView:(UICollectionView *)collectionView prefetchItemsAtIndexPaths:(NSArray *)indexPaths NS_AVAILABLE_IOS(10_0);

- (void)collectionView:(UICollectionView *)collectionView cancelPrefetchingForItemsAtIndexPaths:(NSArray *)indexPaths ?NS_AVAILABLE_IOS(10_0);

在ColletionView prefetchItemsAt indexPaths這個方法是異步預加載數據的,當中的indexPaths數組是有序的,就是item接收數據的順序;

CollectionView cancelPrefetcingForItemsAt indexPaths這個方法是可選的,可以用來處理在滑動中取消或者降低提前加載數據的優先級.

注意:這個協議并不能代替之前讀取數據的方法,僅僅是輔助加載數據.

Pre-Fetching預加載對UITableViewCell同樣適用.

10.UIRefreshControl的使用

在iOS 10 中, UIRefreshControl可以直接在UICollectionView和UITableView中使用,并且脫離了UITableViewController.現在RefreshControl是UIScrollView的一個屬性.

使用方法:

UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];

[refreshControl addTarget:self action:@selector(loadData) forControlEvents:UIControlEventValueChanged];

collectionView.refreshControl = refreshControl;

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,156評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,401評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,069評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,873評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,635評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,128評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,203評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,365評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,881評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,733評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,935評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,475評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,172評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,582評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,821評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,595評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,908評論 2 372

推薦閱讀更多精彩內容

  • 2016-09-20 iOS開發 文/Eternaldream(授權) 原文鏈接:http://www.jians...
    iOS暮光閱讀 2,047評論 2 14
  • 隨著iOS10發布的臨近,大家的App都需要適配iOS10,下面是我總結的一些關于iOS10適配方面的問題,如果有...
    面條168閱讀 846評論 0 1
  • 隨著iOS10發布的臨近,大家的App都需要適配iOS10,下面是我總結的一些關于iOS10適配方面的問題,如果有...
    Eternaldream閱讀 58,696評論 58 333
  • 一、證書管理用Xcode8打開工程后,比較明顯的就是下圖了,這個是蘋果的新特性,可以幫助我們自動管理證書。建議大家...
    seventhboy閱讀 1,538評論 0 2
  • 隨著iOS10發布的臨近,大家的App都需要適配iOS10,下面是我總結的一些關于iOS10適配方面的問題,如果有...
    心淡然如水閱讀 491評論 0 0