一.前言介紹
? ? ? ?此文檔描述了從iOS8.0到目前的iOS13版本更新需要兼容的地方--- 僅供iOS開發(fā)人員參考
二.iOS 8.0
1.定位功能使用改變
// 判斷定位操作是否被允許if([CLLocationManager locationServicesEnabled]) { ? ?locationManager = [[CLLocationManager alloc] init]; ? ?locationManager.delegate = self; ? ?[locationManager startUpdatingLocation];}else?{ ? ?//提示用戶無法進(jìn)行定位操作}
如果在iOS8下用這樣的方式交胚,你會(huì)發(fā)現(xiàn)無法定位份汗,那是因?yàn)閕OS8下添加了新的方法
?/表示使用應(yīng)用程序期間 ?開啟定位 ?
- (void)requestWhenInUseAuthorization ?
//表示始終 開啟定位 ?
- (void)requestAlwaysAuthorization
兩者區(qū)別在于,iOS7 開始蝴簇,有更強(qiáng)大的后臺(tái)運(yùn)行功能杯活,如果 用 requestAlwaysAuthorization 方法,則表示后臺(tái)運(yùn)行時(shí)也會(huì)用到定位
iOS8 下使用系統(tǒng)定位如下:
/ 判斷定位操作是否被允許 ?
?if([CLLocationManager locationServicesEnabled]) { ?
? ? ? ? locationManager = [[CLLocationManager alloc] init]; ?
? ? ? ? locationManager.delegate = self; ?
?//兼容iOS8定位 ?
? ? ? ? SEL requestSelector = NSSelectorFromString(@"requestWhenInUseAuthorization"); ?
?if?([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined &&
? ? ? ? ? ? [locationManager respondsToSelector:requestSelector]) { ?
? ? ? ? ? ? [locationManager requestWhenInUseAuthorization]; ?
}?else?{
? ? ? ? ? ? [locationManager startUpdatingLocation]; ?
? ? ? ? } ?
?return?YES;
? ? }else?{
?//提示用戶無法進(jìn)行定位操作 ?
? ? } ?
?return?NO;
除了這些熬词,你還需要在 info.plist 里面添加新的鍵值旁钧,否則 也是無法定位的
2.UIActionSheet and UIAlertView 的升級(jí)
在iOS8里面,官方提供了新的類UIAlertController來替換UIActionSheet and UIAlertView荡澎。
UIAlertController* alert = [UIAlertController?alertControllerWithTitle:@"My Alert"??message:@"This is an alert."??preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction defaultAction = [UIAlertAction?actionWithTitle:@"OK"style:UIAlertActionStyleDefault?handler:^(UIAlertAction ?action) {}];
[self?presentViewController:alert?animated:YES?completion:nil];
3.解決跳轉(zhuǎn)到系統(tǒng)設(shè)置里自己App的頁面
在iOS5.0時(shí)時(shí)可以跳轉(zhuǎn)到系統(tǒng)的設(shè)置頁的均践。但是在5.1之后就不可以了晤锹。
剛才研究了下這個(gè)問題摩幔,發(fā)現(xiàn)只有iOS8可以跳轉(zhuǎn)到系統(tǒng)設(shè)置里自己App的頁面。
目前沒有找到iOS7怎么跳轉(zhuǎn)過去鞭铆。如果你知道請(qǐng)一定要留言告知或衡,Thanks!
下面說下iOS8是如何跳轉(zhuǎn)的,以下是代碼:
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if?([[UIApplication sharedApplication] canOpenURL:url]) {
? ?[[UIApplication sharedApplication] openURL:url];
}
三.iOS 9.0
1.?后臺(tái)定位類app適配點(diǎn)
在iOS8中车遂,APP的定位服務(wù)apple就做了一些修改封断,需要用戶申請(qǐng)相應(yīng)的權(quán)限,并在info.plist文件中添加對(duì)應(yīng)的鍵值
在iOS9系統(tǒng)中舶担,定位服務(wù)的做法基本沒有改變坡疼,對(duì)于前臺(tái)的定位沒有影響,但app中如果需要后臺(tái)定位衣陶,那么還需要多做一些操作柄瑰,例如:
manager = [[CLLocationManager alloc]init];
?//申請(qǐng)后臺(tái)定位權(quán)限
? ? [manager requestAlwaysAuthorization];
? ? manager.delegate=self;
?//=======================================
?//下面這個(gè)是iOS9中新增的方法 開啟后臺(tái)定位
? ? manager.allowsBackgroundLocationUpdates = YES;
?//======================================
? ? [manager startUpdatingLocation];
通過上面簡(jiǎn)單的配置直接運(yùn)行的話闸氮,程序會(huì)崩潰掉,還需要在plist文件中做一些配置
2.?安裝不受信任的開發(fā)者應(yīng)用
我們知道教沾,在Xcode7后蒲跨,開發(fā)者可以不用花99dollars去購買開發(fā)者賬號(hào)而可以在自己的iphone上進(jìn)行測(cè)試。在安裝這些應(yīng)用時(shí)授翻,iOS9系統(tǒng)不再向以前那樣或悲,再安裝時(shí)提示一個(gè)信任的按鈕。
3.?BitCode的配置
BitCode是app的一種中間形式堪唐,在iOS9系列專題的前幾篇巡语,有對(duì)其的簡(jiǎn)單介紹,舉個(gè)例子羔杨,我們可以在提交app時(shí)提交app的bitcode形式捌臊,如此一來,apple會(huì)對(duì)我們的app進(jìn)行二次優(yōu)化兜材,在用戶下載時(shí)根據(jù)所需再進(jìn)行編譯打包理澎。在Xocde7中,新建的項(xiàng)目是默認(rèn)開啟BitCode的曙寡,如果我們用Xcode7編譯提交應(yīng)用糠爬,這里有需要注意適配的地方。
如果要支持BitCode举庶,需要保證所有的SDK都支持BitCode执隧,如果要更新舊的SDK,只需要在Xcode7上開啟BitCode重新制作一遍即可户侥。
如果不能使所有SDK都支持BitCode镀琉,可以在項(xiàng)目中關(guān)閉BitCode,在building Setting中搜索BitCode蕊唐,將enable設(shè)置為NO屋摔。
4.?URL Scheme白名單
在iOS9中,apple引入了白名單這個(gè)概念替梨,其好處是對(duì)app應(yīng)用內(nèi)安全進(jìn)行了加強(qiáng)钓试。在iOS9的適配中,如果我們用到canOpenURL這樣的方法副瀑,則需要配置白名單弓熏。
首先,我們創(chuàng)建一個(gè)測(cè)試工程糠睡,什么都不用做挽鞠,只需要添加一個(gè)URL Scheme
?|
在另一個(gè)工程中,我們寫如下代碼:
BOOL can= [[UIApplication sharedApplication]canOpenURL:[NSURL URLWithString:@"TEST://"]];
? ? NSLog(@"%d",can);
? ? [[UIApplication sharedApplication]openURL:[NSURL URLWithString:@"TEST://"]];
5.?iOS9網(wǎng)絡(luò)適配_ATS:改用更安全的HTTPS
為了強(qiáng)制增強(qiáng)數(shù)據(jù)訪問安全, iOS9 默認(rèn)會(huì)把 所有的http請(qǐng)求 所有從NSURLConnection 信认、 CFURL 串稀、 NSURLSession發(fā)出的 HTTP 請(qǐng)求,都改為 HTTPS 請(qǐng)求:iOS9.x-SDK編譯時(shí)狮杨,默認(rèn)會(huì)讓所有從NSURLConnection 母截、 CFURL 、 NSURLSession發(fā)出的 HTTP 請(qǐng)求統(tǒng)一采用TLS 1.2 協(xié)議橄教。因?yàn)?AFNetworking 現(xiàn)在的版本底層使用了 NSURLConnection 清寇,眾多App將被影響(基于iOS8.x-SDK的App不受影響)。服務(wù)器因此需要更新护蝶,以解析相關(guān)數(shù)據(jù)华烟。如不更新,可通過在 Info.plist 中聲明持灰,倒退回不安全的網(wǎng)絡(luò)請(qǐng)求盔夜。而這一做法,官方文檔稱為ATS堤魁,全稱為App Transport Security喂链,是iOS9的一個(gè)新特性。
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSAppTransportSecurity</key>
<dict>
?<key>NSExceptionDomains</key>
?<dict>
?<key>yourserver.com</key>
?<dict>
?<!--Include to allow subdomains-->
?<key>NSIncludesSubdomains</key>
?<true/>
?<!--Include to allow insecure HTTP requests-->
?<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
?<true/>
?<!--Include to specify minimum TLS version-->
?<key>NSTemporaryExceptionMinimumTLSVersion</key>
?<string>TLSv1.1</string>
?</dict>
?</dict>
</dict>
四.iOS 10.0
1.?Notification(通知)
所有相關(guān)通知被統(tǒng)一到了UserNotifications.framework框架中
增加了撤銷妥泉、更新椭微、中途還可以修改通知的內(nèi)容
通知不在是簡(jiǎn)單的文本了,可以加入視頻盲链、圖片蝇率,自定義通知的展示等等。
iOS 10相對(duì)之前的通知來說更加好用易于管理刽沾,并且進(jìn)行了大規(guī)模優(yōu)化本慕,對(duì)于開發(fā)者來說是一件好事
iOS 10開始對(duì)于權(quán)限問題進(jìn)行了優(yōu)化,申請(qǐng)權(quán)限就比較簡(jiǎn)單了(本地與遠(yuǎn)程通知集成在一個(gè)方法中)侧漓。
2.?ATS的問題
iOS 9中默認(rèn)非HTTS的網(wǎng)絡(luò)是被禁止的锅尘,當(dāng)然我們也可以把NSAllowsArbitraryLoads設(shè)置為YES禁用ATS。不過iOS 10從2017年1月1日起蘋果不允許我們通過這個(gè)方法跳過ATS火架,也就是說強(qiáng)制我們用HTTPS鉴象,如果不這樣的話提交App可能會(huì)被拒絕忙菠。但是我們可以通過NSExceptionDomains來針對(duì)特定的域名開放HTTP可以容易通過審核犹赖。
3.?iOS 10 隱私權(quán)限設(shè)置
iOS 10 開始對(duì)隱私權(quán)限更加嚴(yán)格竞漾,如果你不設(shè)置就會(huì)直接崩潰,現(xiàn)在很多遇到崩潰問題了,一般解決辦法都是在info.plist文件添加對(duì)應(yīng)的Key-Value就可以了衬鱼。
?|
4.?iOS 10 UICollectionView 性能優(yōu)化
隨著開發(fā)者對(duì)UICollectionView的信賴,項(xiàng)目中用的地方也比較多,但是還是存在一些問題,比如有時(shí)會(huì)卡頓犹菱、加載慢等。所以iOS 10 對(duì)UICollectionView進(jìn)一步的優(yōu)化吮炕。
UICollectionView cell pre-fetching預(yù)加載機(jī)制
UICollectionView and UITableView prefetchDataSource 新增的API
針對(duì)self-sizing cells 的改進(jìn)
5.?UITextContentType
在iOS 10 UITextField添加了textContentType枚舉腊脱,指示文本輸入?yún)^(qū)域所期望的語義意義。
使用此屬性可以給鍵盤和系統(tǒng)信息龙亲,關(guān)于用戶輸入的內(nèi)容的預(yù)期的語義意義陕凹。例如,您可以指定一個(gè)文本字段鳄炉,用戶填寫收到一封電子郵件確認(rèn)uitextcontenttypeemailaddress杜耙。當(dāng)您提供有關(guān)您期望用戶在文本輸入?yún)^(qū)域中輸入的內(nèi)容的信息時(shí),系統(tǒng)可以在某些情況下自動(dòng)選擇適當(dāng)?shù)逆I盤拂盯,并提高鍵盤修正和主動(dòng)與其他文本輸入機(jī)會(huì)的整合佑女。
6.?字體隨著手機(jī)系統(tǒng)字體而改變
當(dāng)我們手機(jī)系統(tǒng)字體改變了之后,那我們App的label也會(huì)跟著一起變化谈竿,這需要我們寫很多代碼來進(jìn)一步處理才能實(shí)現(xiàn)团驱,但是iOS 10 提供了這樣的屬性adjustsFontForContentSizeCategory來設(shè)置。因?yàn)闆]有真機(jī)空凸,具體實(shí)際操作還沒去實(shí)現(xiàn)店茶,如果理解錯(cuò)誤幫忙指正。
UILabel *myLabel = [UILabel?new];?/*
? ? UIFont 的preferredFontForTextStyle: 意思是指定一個(gè)樣式劫恒,并讓字體大小符合用戶設(shè)定的字體大小贩幻。
? ?*/
myLabel.font =[UIFont preferredFontForTextStyle: UIFontTextStyleHeadline];?/*
?Indicates whether the corresponding element should automatically update its font when the device’s UIContentSizeCategory is changed.
?For this property to take effect, the element’s font must be a font vended using +preferredFontForTextStyle: or +preferredFontForTextStyle:compatibleWithTraitCollection: with a valid UIFontTextStyle.
?*/
? ? ?//是否更新字體的變化
? ? myLabel.adjustsFontForContentSizeCategory = YES;
7.?系統(tǒng)版本判斷方法失效
我們之前的系統(tǒng)版本方法如下
當(dāng)系統(tǒng)版本到iOS10.0的時(shí)候 9.0和10.0比較的話是降序而不是升序,這樣會(huì)導(dǎo)致iOS10.0是最早的版本两嘴,這樣后面要走的iOS10的方法可能都不會(huì)走而出現(xiàn)問題
#define?IOS9_OR_LATER ([[[UIDevice currentDevice] systemVersion] compare:@"9.0"] != NSOrderedAscending)
#define?IOS8_OR_LATER ([[[UIDevice currentDevice] systemVersion] compare:@"8.0"] != NSOrderedAscending)
#define?IOS7_OR_LATER ([[[UIDevice currentDevice] systemVersion] compare:@"7.0"] != NSOrderedAscending)
#define?IOS6_OR_LATER ([[[UIDevice currentDevice] systemVersion] compare:@"6.0"] != NSOrderedAscending)
下面這樣也不行它會(huì)永遠(yuǎn)返回NO,substringToIndex:1在iOS 10 會(huì)被檢測(cè)成 iOS 1了,
#define isiOS10 ([[[[UIDevice currentDevice] systemVersion] substringToIndex:1] intValue]>=10)
正確的打開方式應(yīng)該是:
#define?IOS10_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0)
#define?IOS9_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0)
#define?IOS8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
#define?IOS7_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
#define?IOS6_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0)
8.?Xcode8 debug輸出不相關(guān)信息
升級(jí)到Xcode8時(shí)丛楚,我們?cè)赿ebug的時(shí)候控制臺(tái)輸出了很長(zhǎng)很長(zhǎng)的信息,看著比較煩憔辫,怎么屏蔽呢趣些?
需要edit Scheme添加一個(gè)鍵值對(duì)就ok了。
?|
?|
添加 key:?OS_ACTIVITY_MODE??value:?disable?
9.App跳轉(zhuǎn)設(shè)置
? openUrl:
? openURL: options: completionHandler:
? prefs:root=某項(xiàng)服務(wù)
若要跳轉(zhuǎn)系統(tǒng)設(shè)置贰您,需先再URL type中添加一個(gè)prefs值坏平,如下圖:
?|
10.?判斷版本方法
【【UIDevice currentDevice】systemVersion】
11.推送xcode適配開關(guān)
在targets的Capabiliies內(nèi)Push Notifications選項(xiàng)開關(guān)打開
?|
然后Background Modes打開如下幾個(gè)選項(xiàng)
?|
General內(nèi)導(dǎo)入U(xiǎn)serNotifications.framework
?|
12.Xib文件
1) 使用Xcode8 打開xib文件是會(huì)出現(xiàn)“choose an initial device view”的提示,直接選擇藍(lán)色的 choose Device 就可以了锦亦。
2) 如果布局混亂舶替,在xib的右下角更新一下,即 Update Frame杠园。
13.代碼及API
1) UIView的代理方法可能會(huì)出現(xiàn)報(bào)錯(cuò)顾瞪,刪除NSError前面的 nullable就行了。
2) UIStatusBar的方法過期了,如果項(xiàng)目中設(shè)置了statusBar陈醒,那就像下面這樣寫:
- (UIStatusBarStyle)preferredStatusBarStyle {?
?return?UIStatusBarStyleDefault;
}
五.iOS 11.0
1.XCode9運(yùn)行訪問系統(tǒng)相冊(cè)崩潰問題
現(xiàn)象:如圖保存圖片功能惕橙,在XCode9下運(yùn)行會(huì)崩潰
原因:info.plist新增了權(quán)限配置
解決:info.plist新增一條權(quán)限:Privacy - Photo Library Additions Usage Description
2.無法獲取定位信息,第一次打開app也無法彈出定位權(quán)限提示框
iOS11 定位相關(guān)的權(quán)限做了更改钉跷,在iOS11上使用了新的定位權(quán)限key
解決方案:
如果原來申請(qǐng)的權(quán)限是始終允許NSLocationAlwaysUsageDescription弥鹦,那么需要在保留原來的key的基礎(chǔ)上增加NSLocationWhenInUseUsageDescription和NSLocationAlwaysAndWhenInUsageDescription。
3.無線真機(jī)測(cè)試
這應(yīng)該也是?xcode 9?的一個(gè)亮點(diǎn)吧爷辙,但是速度真的不是很干恭維的惶凝。注意手機(jī)和電腦必須在同一個(gè)局域網(wǎng)內(nèi)
首先使用手機(jī)連接xcode之后,打開?window->Devices and Simulator->勾選Show as run destination和Connect via network?,這樣就可以無線測(cè)試了犬钢,以后媽媽再也不用擔(dān)心忘記帶線了
?|
?|
iOS11UI方面的適配較多苍鲜,如啟動(dòng)圖、tabbar玷犹、劉海兒混滔、導(dǎo)航欄、啟動(dòng)圖等適配這些UI方面的適配就沒有整理了歹颓。坯屿。。巍扛。领跛。。
六.iOS 12.0
1.代碼中判斷是否是iPhone X方法
之前很多人判斷手機(jī)是否是iPhone X的方法是根據(jù)手機(jī)尺寸來的.因?yàn)樾枰獙?duì)劉海做特殊處理.現(xiàn)在這種方法可能不行了.
可以根據(jù)其他的方法,比如StatusBar或者底部安全距離來判斷.
#define?rmStatusBarH ([UIApplication sharedApplication].statusBarFrame.size.height)//(44/20)
#define?KIsiPhoneX ((rmStatusBarH == 44.0) ? YES : NO)
也可以:
#define isIPhoneXSeries ? ? ([UIScreen instancesRespondToSelector:@selector(currentMode)] ?\
(\
CGSizeEqualToSize(CGSizeMake(375,?812),[UIScreen mainScreen].bounds.size)\
?||\
CGSizeEqualToSize(CGSizeMake(414,?896),[UIScreen mainScreen].bounds.size)\
)\
:\
NO)
2.升級(jí)Xcode10后項(xiàng)目報(bào)錯(cuò)
項(xiàng)目中如果使用Cocoapods引用了第三方的庫,有可能會(huì)升級(jí)之后導(dǎo)致編譯失敗.
由于我項(xiàng)目中沒有使用cocoapods,所以沒有遇到,網(wǎng)上查了一下資料,大概是因?yàn)?
iOS 12移除了libstdc++, 用libc++替代:
多個(gè) info.plist 會(huì)引起崩潰.
可以將多余的info.plist刪除
建議方案:
Xcode->File->Project Settings-> Build System -> Legacy Build System.
3.Multiple commands produce 'xxx/Info.plist'
升級(jí)?Xcode 10?之后撤奸,編譯之前的項(xiàng)目吠昭,發(fā)生編譯錯(cuò)誤:?Multiple commands produce 'xxx/Info.plist'?,項(xiàng)目中存在重復(fù)命名的info.plist文件胧瓜。
解決方案:
(I)標(biāo)準(zhǔn)方案:刪除所有重復(fù)命名的文件矢棚。
(II)臨時(shí)方案:
?xcworkspace?項(xiàng)目:Xcode菜單欄?File??->??Workspace Settings??->??Build System??->??Legacy Build System?;
?xcodeprj?項(xiàng)目:Xcode菜單欄?File??->??Project Settings??->??Build System??->??Legacy Build System?府喳。
4.?iOS 12?系統(tǒng)?WiFi?獲取?SSID?(wifi名稱)和?BSSID?(mac地址)失敗
在?iOS 12?系統(tǒng)之后蒲肋,蘋果提升了獲取?WiFi?名稱和?mac?地址的權(quán)限控制,要獲取這些信息钝满,需要手動(dòng)為應(yīng)用打開獲取WiFi信息的權(quán)限兜粘。
解決方案:
在開發(fā)者賬號(hào)中,勾選項(xiàng)目的?App ID?的?Access WiFi Infomation?選項(xiàng)弯蚜;
在Xcode的?Capabilities?中孔轴,勾選項(xiàng)目的?Access WiFi Infomation?選項(xiàng)。
5.?Xcode 10?中?#import?的時(shí)候閃退或?qū)腩^文件不提示
在?Xcode 10?中出現(xiàn)輸入?#import?引入文件/類庫頭文件的時(shí)候?Xcode?閃退熟吏【嗵牵或者輸入?#import?導(dǎo)入頭文件時(shí)不提示。
解決方案:
?xcworkspace?項(xiàng)目:Xcode菜單欄?File??->??Workspace Settings??->??Build System??->??Legacy Build System?牵寺;
?xcodeprj?項(xiàng)目:Xcode菜單欄?File??->??Project Settings??->??Build System??->??Legacy Build System?悍引。
6.?webView?播放視頻返回后狀態(tài)欄消失
視頻播放完成主?window?成為?KeyWindow?的時(shí)候仍隱藏著?UIStatusBar?。
解決方案:
- (void)videoPlayerFinishedToShowStatusBar
{
?if?(@available(iOS 12.0, *)) {
? ? ? ? [[NSNotificationCenter defaultCenter] addObserverForName:UIWindowDidBecomeKeyNotification
?object:self.window
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?queue:[NSOperationQueue mainQueue]
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? usingBlock:^(NSNotification * _Nonnull note) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? [[UIApplication sharedApplication] setStatusBarHidden:NO
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? withAnimation:UIStatusBarAnimationNone];
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }];
? ? }
}
7.Xcode 10 ?imageNamed: 不能正常加載Assets里面的圖片
imageNamed:加載Assets中的圖片出來是nil帽氓,將圖片放到bundle中即可趣斤。
七.iOS 13.0
1.私有KVC
iOS不允許?valueForKey?、?setValue: forKey?獲取和設(shè)置私有屬性黎休,需要使用其它方式修改
如:
[textField setValue:[UIColor red] forKeyPath:@"_placeholderLabel.textColor"];
//替換為
textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"輸入"attributes:@{NSForegroundColorAttributeName: [UIColor red]}];
2.黑線處理crash
之前為了處理搜索框的黑線問題會(huì)遍歷后刪除?UISearchBarBackground?浓领,在iOS13會(huì)導(dǎo)致UI渲染失敗crash;解決辦法是設(shè)置?UISearchBarBackground?的layer.contents為nil
public?func?clearBlackLine()?{
?for?view in self.subviews.last!.subviews {
?if?view.isKind(of: NSClassFromString("UISearchBarBackground")!) {
? ? ? ? ? ? ? ? view.backgroundColor = UIColor.white
view.layer.contents =?nil
?break
? ? ? ? ? ? }
? ? ? ? }
? ? }
3.模態(tài)跳轉(zhuǎn)(modal present)
iOS13模態(tài)跳轉(zhuǎn)出來的界面,不再像之前版本是全屏的了
如果將此屬性設(shè)置為?UIModalPresentationAutomatic?势腮,則讀取該屬性將始終返回具體的呈現(xiàn)樣式联贩。 默認(rèn)情況下,?UIViewController?將?UIModalPresentationAutomatic?解析為?UIModalPresentationPageSheet?捎拯,但是系統(tǒng)提供的子類可以將?UIModalPresentationAutomatic?解析為其他具體的呈現(xiàn)樣式泪幌。 保留?UIModalPresentationAutomatic?的分辨率供系統(tǒng)提供的視圖控制器使用。從iOS 13.0開始署照,在iOS上默認(rèn)為?UIModalPresentationAutomatic?祸泪,在以前的版本上默認(rèn)為?UIModalPresentationFullScreen?。 在所有其他平臺(tái)上建芙,默認(rèn)為?UIModalPresentationFullScreen?没隘。
?UIModalPresentationPageSheet?就是下面的樣子
?|
知道了原因,我們做適配也簡(jiǎn)單了禁荸,就是設(shè)置下屬性的事:
let second = SecondViewController()
second.modalPresentationStyle = .fullScreen
present(second, animated:?true, completion:?nil)
4.暗黑模式
iOS13使用暗黑模式時(shí)右蒲,UIView默認(rèn)背景色會(huì)變成暗黑色。適配暗黑模式的工作量較大赶熟,改為強(qiáng)制使用正常模式品嚣。
處理方案:在plist文件中增加配置項(xiàng)UIUserInterfaceStyle,值為L(zhǎng)ight钧大。
5.藍(lán)牙權(quán)限更新
上傳App Store時(shí)翰撑,如果引用了CoreBluetooth.framework,則需要添加描述配置?NSBluetoothAlwaysUsageDescription?啊央,否則無法提交眶诈。舊版本的個(gè)推SDK引入時(shí)依賴CoreBluetooth,后續(xù)版本已修改不再依賴CoreBluetooth瓜饥。
處理方案:檢查其他第三方庫并未依賴CoreBluetooth.framework逝撬,刪除對(duì)該庫的引用。
6.廢棄UIWebview改為WKWebView
暫時(shí)沒有強(qiáng)制修改乓土,但是已經(jīng)發(fā)郵件提示宪潮,需要做一下修改溯警,否則可能無法上架哈
7.KVC限制
在iOS13上通過KVC來修改系統(tǒng)API私有屬性時(shí)會(huì)報(bào)錯(cuò)
*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Access to xxx's _xxx ivar is prohibited. This is an application bug'
處理方案:
1、全局搜索KVC的使用方法狡相,未發(fā)現(xiàn)使用KVC方式修改私有屬性的代碼
2梯轻、平時(shí)開發(fā)時(shí)注意KVC的使用
8. 第三方登錄支持蘋果登錄(Sign In with Apple)
蘋果更新了審核指南,要求所有專門使用第三方登錄的App尽棕,2020 年 4 月之前喳挑,都必須接入 Sign in with Apple。符合以下條件的App滔悉,可以不接入:
使用自建賬戶和登錄系統(tǒng)伊诵;
要求用戶使用現(xiàn)有的教育或企業(yè)賬戶登錄的教育、企業(yè)或商業(yè)類應(yīng)用回官;
使用政府或行業(yè)支持的公民身份識(shí)別系統(tǒng)或電子 ID 來驗(yàn)證用戶曹宴;
應(yīng)用特定于第三方服務(wù),用戶需要使用郵箱歉提、社交媒體或其它第三方賬戶才能訪問其內(nèi)容的應(yīng)用浙炼;
9.使用MJExtension 中處理NSNull的不同
這個(gè)直接會(huì)導(dǎo)致Crash的在將服務(wù)端數(shù)據(jù)字典轉(zhuǎn)換為模型時(shí),如果遇到服務(wù)端給的數(shù)據(jù)為NSNull時(shí)唯袄,
mj_JSONObject弯屈,其中 class_copyPropertyList方法得到的屬性里,多了一種EFSQLBinding類型的東西恋拷,而且屬性數(shù)量也不準(zhǔn)確资厉,
那就沒辦法了,
我只能改寫這個(gè)方法了蔬顾,這個(gè)組件沒有更新的情況下宴偿,寫了一個(gè)方法swizzling掉把當(dāng)遇到 NSNull時(shí),直接轉(zhuǎn)為nil了诀豁。
10.WKWebView 中測(cè)量頁面內(nèi)容高度的方式變更
iOS 13以前
document.body.scrollHeight
iOS 13中
document.documentElement.scrollHeight
兩者相差55 應(yīng)該是瀏覽器定義高度變了
11. 友盟消息推送窄刘,獲取deviceToken適配
- (void)application:(UIApplication *)applicationdidRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{if(![deviceToken isKindOfClass:[NSData class]])return; ? ? ?const?unsigned?*tokenBytes = (constunsigned?*)[deviceToken bytes]; ? ? ?NSString *hexToken = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),ntohl(tokenBytes[6]),ntohl(tokenBytes[7])]; ? ? ?pushDeviceToken = hexToken; ? ? ?NSLog(@"deviceToken:%@",hexToken);}
12.獲取Wi-Fi名
iOS12之前
id info =?nil;
? ? NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
?for?(NSString *ifnam?in?ifs) {
? ? ? ? info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
? ? ? ? NSString *str = info[@"SSID"];//name
? ? }
iOS 12之后以上方法獲取不到,需要在Xcode中TARGET-->Capabilities打開Access WiFi Information選項(xiàng)
?|
iOS 13之后以上方法獲取Wi-Fi名返回的都是固定值"WLAN"舷胜,這里可能是因?yàn)樘O果保護(hù)用戶隱私而產(chǎn)生的問題娩践,因?yàn)橥ㄟ^wifi信息可以定位到用戶地理位置。所以iOS13以后如果想要繼續(xù)獲取WiFi名稱烹骨,需要在調(diào)用接口前判斷用戶是否同意App使用地理位置信息翻伺。可以在程序一啟動(dòng)時(shí)請(qǐng)求用戶權(quán)限沮焕,調(diào)用的方法如下:
#import <CoreLocation/CoreLocation.h>
@property (strong, nonatomic) CLLocationManager *locationManager;
NSString* phoneVersion = [[UIDevice currentDevice] systemVersion];
CGFloat version = [phoneVersion floatValue];
// 如果是iOS13 未開啟地理位置權(quán)限 需要提示一下
if?([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined && version >=?13) {
?self.locationManager = [[CLLocationManager alloc] init];
? ? [self.locationManager requestWhenInUseAuthorization];
}
如果用戶拒絕了授權(quán)吨岭,在需要獲取Wi-Fi名的界面加上提示:
? ? NSString* phoneVersion = [[UIDevice currentDevice] systemVersion];
? ? CGFloat version = [phoneVersion floatValue];
? ? //如果開啟地理位置權(quán)限未開啟 需要提示一下
?if?(([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined?||[CLLocationManager authorizationStatus] == kCLAuthorizationStatusRestricted?||[CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied ?)&& version >=?13) {
[PracticalTools?showAlertViewWithTitle:@"提示"?message:@"您的位置權(quán)限尚未授權(quán),將無法獲取當(dāng)前Wi-Fi進(jìn)行配置網(wǎng)絡(luò)峦树,請(qǐng)前往“設(shè)置”-“****App”-“位置”進(jìn)行授權(quán)辣辫!"?doneText:@"確定"?cancelText:nildoneHandle:nil?cancelHandle:nil?vc:self];
? ? }
13.iOS13 正確的獲得Devicetoken
#include?<arpa/inet.h>
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
?if?(![deviceToken isKindOfClass:[NSData class]])?return;
?const?unsigned?*tokenBytes = (const?unsigned?*)[deviceToken bytes];
? ? NSString *hexToken = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
? ? ? ? ? ? ? ? ? ? ? ? ? ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
? ? ? ? ? ? ? ? ? ? ? ? ? ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
? ? ? ? ? ? ? ? ? ? ? ? ? ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
? ? NSLog(@"deviceToken:%@",hexToken);
}
14.Xcode 11 創(chuàng)建的工程在低版本設(shè)備上運(yùn)行黑屏
使用 Xcode 11 創(chuàng)建的工程旦事,運(yùn)行設(shè)備選擇 iOS 13.0 以下的設(shè)備,運(yùn)行應(yīng)用時(shí)會(huì)出現(xiàn)黑屏急灭。這是因?yàn)?Xcode 11 默認(rèn)是會(huì)創(chuàng)建通過 UIScene 管理多個(gè) UIWindow 的應(yīng)用姐浮,工程中除了 AppDelegate 外會(huì)多一個(gè) SceneDelegate.
?|
這是為了 iPadOS 的多進(jìn)程準(zhǔn)備的,也就是說 UIWindow 不再是 UIApplication 中管理化戳。但是舊版本根本沒有 UIScene单料,因此解決方案就是在 AppDelegate 的頭文件加上:
@property (strong, nonatomic) UIWindow *window;
15.NSAttributedString優(yōu)化
對(duì)于UILabel埋凯、UITextField点楼、UITextView,在設(shè)置NSAttributedString時(shí)也要考慮適配Dark Mode白对,否則在切換模式時(shí)會(huì)與背景色融合掠廓,造成不好的體驗(yàn)
不建議的做法
NSDictionary *dic = @{NSFontAttributeName:[UIFont systemFontOfSize:16]};
NSAttributedString *str = [[NSAttributedString alloc] initWithString:@"富文本文案"attributes:dic];
推薦的做法
// 添加一個(gè)NSForegroundColorAttributeName屬性
NSDictionary *dic = @{NSFontAttributeName:[UIFont systemFontOfSize:16],NSForegroundColorAttributeName:[UIColor labelColor]};
NSAttributedString *str = [[NSAttributedString alloc] initWithString:@"富文本文案"attributes:dic];