原文請(qǐng)見(jiàn)github上iOS10升級(jí)后的一些問(wèn)題
iOS10升級(jí)
在2016年9月14日凌晨iOS10系統(tǒng)準(zhǔn)時(shí)推送過(guò)來(lái)了,作為懶人之前的beta版一直沒(méi)有升級(jí)試用。今天果斷手機(jī)和Xcode一起升級(jí)了,新系統(tǒng)新面貌帶來(lái)新bug。記錄一下升級(jí)iOS10和Xcode8.0后遇到的問(wèn)題。
開(kāi)發(fā)者證書(shū)不能使用
General里面Signing變成如下樣子,Automatically manage signing 自動(dòng)簽名管理。報(bào)錯(cuò)了,之前一直使用的企業(yè)級(jí)開(kāi)發(fā)者證書(shū)不可用了。

Build Settings 里面的 Code Signing Identity 清一色選擇為企業(yè)級(jí)開(kāi)發(fā)者證書(shū)。還是報(bào)錯(cuò)


解決辦法:
取消Automatically manage signing的選擇,會(huì)出現(xiàn)兩個(gè)Signing,分別對(duì)應(yīng)Debug和Release,選擇該項(xiàng)目對(duì)應(yīng)使用的Provisioning Profiles即可

注釋快捷鍵command+/失效
Xcode8.0的注釋// 生成快捷鍵 command+/失效了
解決辦法:
終端運(yùn)行命令:sudo /usr/libexec/xpccachectl
Password:輸入開(kāi)機(jī)密碼
重啟Mac生效
生效后空行快捷鍵,只在代碼行能產(chǎn)生/解除注釋?zhuān)招胁荒墚a(chǎn)生注釋。記得之前可以來(lái)這....
Xcode控制臺(tái)輸出問(wèn)題
無(wú)用log打印
升級(jí)Xcode8.0之后運(yùn)行項(xiàng)目,控制臺(tái)瘋狂打印了N多東西,完全看不懂啊,完?duì)僮恿?,這么多需要適配的...
眼不見(jiàn)心不煩,下面就提供去掉這些亂七八糟打印內(nèi)容的方法。
解決辦法:
在Edit Scheme...下的Run -> Arguments -> Environment Variables 添加 OS_ACTIVITY_MODE = disable
具體見(jiàn)下圖

真機(jī)測(cè)試log屏蔽
經(jīng)過(guò)上述修改,在iOS10模擬器中無(wú)用的log輸出被屏蔽了,但是真機(jī)測(cè)試的時(shí)候,沒(méi)有l(wèi)og輸出,log日志被完全屏蔽了。不知是屏蔽無(wú)用log的設(shè)置,還是xcode8為了提高真機(jī)測(cè)試性能屏蔽了log日志?真機(jī)測(cè)試的log也很重要。
為了app正式發(fā)布時(shí)不打印log,讓打印操作NSLog只在Debug環(huán)境下運(yùn)行,采用了下面的辦法自定義NSLog:
#ifdef DEBUG
#define XDLog(...) NSLog(__VA_ARGS__)
#else
#define XDLog(...)
#endif
iOS10之后,在真機(jī)中NSLog無(wú)法打印log,可以使用printf(),具體修改見(jiàn)下面自定義log:
#ifdef DEBUG
#define XDString [NSString stringWithFormat:@"%s", __FILE__].lastPathComponent
#define XDLog(...) printf("%s %d行: %s\n\n",[XDString UTF8String], __LINE__, [[NSString stringWithFormat:__VA_ARGS__] UTF8String]);
#else
#define XDLog(...)
#endif
XDString是獲取的該log在哪個(gè)文件里,__LINE__該log在第幾行。printf()是c語(yǔ)言方法,所以要用UTF8String轉(zhuǎn)義,不然每個(gè)log都會(huì)有警告。
類(lèi)型判斷
網(wǎng)絡(luò)獲取數(shù)據(jù),做容錯(cuò)處理,判斷某個(gè)字段是否符合需要的數(shù)據(jù)類(lèi)型。之前一度用如下判斷方法:
[NSStringFromClass([userDict[@"plates"] class]) isEqualToString:@"__NSCFArray"]
如果userDict[@"plates"]的數(shù)據(jù)類(lèi)型是數(shù)組的話(huà),打印出來(lái)的就是__NSCFArray類(lèi)型。同樣如果是字典類(lèi)型的話(huà),打印出來(lái)的就是__NSCFDictionary。但是iOS10之后,打印出來(lái)的不同了,同樣的數(shù)組類(lèi)型,打印出來(lái)的是__NSSingleObjectArrayI。
之前的這種判斷方法很欠考慮,還是利用下面的方法比較靠譜:
[userDict[@"plates"] isKindOfClass:[NSArray class]]
URL Schemes跳轉(zhuǎn)系統(tǒng)設(shè)置
跳轉(zhuǎn)系統(tǒng)設(shè)置的方法徹底被關(guān)閉了,也就是說(shuō)你已不能從app跳轉(zhuǎn)到系統(tǒng)設(shè)置里了。我的某個(gè)app使用地理定位,運(yùn)行app時(shí)會(huì)檢測(cè)是否開(kāi)啟地理定位,如果未開(kāi)啟,提醒a(bǔ)lert,用如下代碼點(diǎn)擊跳轉(zhuǎn)到地理定位的開(kāi)啟設(shè)置里。
NSURL *url = [NSURL URLWithString:@"prefs:root=LOCATION_SERVICES"];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
}
iOS10以后prefs:root開(kāi)頭的Scheme無(wú)法跳轉(zhuǎn)到系統(tǒng)設(shè)置里了。
plist里聲明獲取隱私數(shù)據(jù)權(quán)限
訪問(wèn)隱私數(shù)據(jù)需要在plist里聲明,在iOS10之前只需要聲明地理定位之類(lèi)的敏感隱私數(shù)據(jù),獲取照片、相機(jī)等不需要再plist里聲明。iOS10之后,這些也必須聲明,不聲明會(huì)crash。需要聲明的用戶(hù)數(shù)據(jù)有:
Contacts(聯(lián)系人), Calendar(日歷), Reminders(提醒事件), Photos(照片), Bluetooth Sharing(藍(lán)牙共享), Microphone(麥克風(fēng)), Camera(相機(jī)), Location(位置), Health(健康), HomeKit(家居), Media Library(媒體庫(kù)), Motion(運(yùn)動(dòng)), CallKit(打電話(huà)), Speech Recognition(語(yǔ)言識(shí)別), SiriKit(Siri), TV Provider(電視提供商).

后面string字段填寫(xiě)彈出用戶(hù)允許時(shí)展示的描述信息。注意,這里必須要寫(xiě)明獲取該權(quán)限的用途,不然會(huì)被AppStore拒絕上架的。