一.前言介紹
? ? ? ?此文檔描述了從iOS8.0到目前的iOS13版本更新需要兼容的地方--- 僅供iOS開發(fā)人員參考
二.iOS 8.0
1.定位功能使用改變
// 判斷定位操作是否被允許if([CLLocationManager locationServicesEnabled]) { ? ?locationManager = [[CLLocationManager alloc] init]; ? ?locationManager.delegate = self; ? ?[locationManager startUpdatingLocation];}else?{ ? ?//提示用戶無法進行定位操作}
如果在iOS8下用這樣的方式,你會發(fā)現(xiàn)無法定位,那是因為iOS8下添加了新的方法
?/表示使用應用程序期間 ?開啟定位 ?
- (void)requestWhenInUseAuthorization ?
//表示始終 開啟定位 ?
- (void)requestAlwaysAuthorization
兩者區(qū)別在于,iOS7 開始,有更強大的后臺運行功能,如果 用 requestAlwaysAuthorization 方法,則表示后臺運行時也會用到定位
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?{
?//提示用戶無法進行定位操作 ?
? ? } ?
?return?NO;
除了這些,你還需要在 info.plist 里面添加新的鍵值,否則 也是無法定位的
2.UIActionSheet and UIAlertView 的升級
在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)設置里自己App的頁面
在iOS5.0時時可以跳轉(zhuǎn)到系統(tǒng)的設置頁的。但是在5.1之后就不可以了。
剛才研究了下這個問題,發(fā)現(xiàn)只有iOS8可以跳轉(zhuǎn)到系統(tǒng)設置里自己App的頁面。
目前沒有找到iOS7怎么跳轉(zhuǎn)過去。如果你知道請一定要留言告知,Thanks!
下面說下iOS8是如何跳轉(zhuǎn)的,以下是代碼:
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if?([[UIApplication sharedApplication] canOpenURL:url]) {
? ?[[UIApplication sharedApplication] openURL:url];
}
三.iOS 9.0
1.?后臺定位類app適配點
在iOS8中,APP的定位服務apple就做了一些修改,需要用戶申請相應的權(quán)限,并在info.plist文件中添加對應的鍵值
在iOS9系統(tǒng)中,定位服務的做法基本沒有改變,對于前臺的定位沒有影響,但app中如果需要后臺定位,那么還需要多做一些操作,例如:
manager = [[CLLocationManager alloc]init];
?//申請后臺定位權(quán)限
? ? [manager requestAlwaysAuthorization];
? ? manager.delegate=self;
?//=======================================
?//下面這個是iOS9中新增的方法 開啟后臺定位
? ? manager.allowsBackgroundLocationUpdates = YES;
?//======================================
? ? [manager startUpdatingLocation];
通過上面簡單的配置直接運行的話,程序會崩潰掉,還需要在plist文件中做一些配置
2.?安裝不受信任的開發(fā)者應用
我們知道,在Xcode7后,開發(fā)者可以不用花99dollars去購買開發(fā)者賬號而可以在自己的iphone上進行測試。在安裝這些應用時,iOS9系統(tǒng)不再向以前那樣,再安裝時提示一個信任的按鈕。
3.?BitCode的配置
BitCode是app的一種中間形式,在iOS9系列專題的前幾篇,有對其的簡單介紹,舉個例子,我們可以在提交app時提交app的bitcode形式,如此一來,apple會對我們的app進行二次優(yōu)化,在用戶下載時根據(jù)所需再進行編譯打包。在Xocde7中,新建的項目是默認開啟BitCode的,如果我們用Xcode7編譯提交應用,這里有需要注意適配的地方。
如果要支持BitCode,需要保證所有的SDK都支持BitCode,如果要更新舊的SDK,只需要在Xcode7上開啟BitCode重新制作一遍即可。
如果不能使所有SDK都支持BitCode,可以在項目中關閉BitCode,在building Setting中搜索BitCode,將enable設置為NO。
4.?URL Scheme白名單
在iOS9中,apple引入了白名單這個概念,其好處是對app應用內(nèi)安全進行了加強。在iOS9的適配中,如果我們用到canOpenURL這樣的方法,則需要配置白名單。
首先,我們創(chuàng)建一個測試工程,什么都不用做,只需要添加一個URL Scheme
?|
在另一個工程中,我們寫如下代碼:
BOOL can= [[UIApplication sharedApplication]canOpenURL:[NSURL URLWithString:@"TEST://"]];
? ? NSLog(@"%d",can);
? ? [[UIApplication sharedApplication]openURL:[NSURL URLWithString:@"TEST://"]];
5.?iOS9網(wǎng)絡適配_ATS:改用更安全的HTTPS
為了強制增強數(shù)據(jù)訪問安全, iOS9 默認會把 所有的http請求 所有從NSURLConnection 、 CFURL 、 NSURLSession發(fā)出的 HTTP 請求,都改為 HTTPS 請求:iOS9.x-SDK編譯時,默認會讓所有從NSURLConnection 、 CFURL 、 NSURLSession發(fā)出的 HTTP 請求統(tǒng)一采用TLS 1.2 協(xié)議。因為 AFNetworking 現(xiàn)在的版本底層使用了 NSURLConnection ,眾多App將被影響(基于iOS8.x-SDK的App不受影響)。服務器因此需要更新,以解析相關數(shù)據(jù)。如不更新,可通過在 Info.plist 中聲明,倒退回不安全的網(wǎng)絡請求。而這一做法,官方文檔稱為ATS,全稱為App Transport Security,是iOS9的一個新特性。
<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(通知)
所有相關通知被統(tǒng)一到了UserNotifications.framework框架中
增加了撤銷、更新、中途還可以修改通知的內(nèi)容
通知不在是簡單的文本了,可以加入視頻、圖片,自定義通知的展示等等。
iOS 10相對之前的通知來說更加好用易于管理,并且進行了大規(guī)模優(yōu)化,對于開發(fā)者來說是一件好事
iOS 10開始對于權(quán)限問題進行了優(yōu)化,申請權(quán)限就比較簡單了(本地與遠程通知集成在一個方法中)。
2.?ATS的問題
iOS 9中默認非HTTS的網(wǎng)絡是被禁止的,當然我們也可以把NSAllowsArbitraryLoads設置為YES禁用ATS。不過iOS 10從2017年1月1日起蘋果不允許我們通過這個方法跳過ATS,也就是說強制我們用HTTPS,如果不這樣的話提交App可能會被拒絕。但是我們可以通過NSExceptionDomains來針對特定的域名開放HTTP可以容易通過審核。
3.?iOS 10 隱私權(quán)限設置
iOS 10 開始對隱私權(quán)限更加嚴格,如果你不設置就會直接崩潰,現(xiàn)在很多遇到崩潰問題了,一般解決辦法都是在info.plist文件添加對應的Key-Value就可以了。
?|
4.?iOS 10 UICollectionView 性能優(yōu)化
隨著開發(fā)者對UICollectionView的信賴,項目中用的地方也比較多,但是還是存在一些問題,比如有時會卡頓、加載慢等。所以iOS 10 對UICollectionView進一步的優(yōu)化。
UICollectionView cell pre-fetching預加載機制
UICollectionView and UITableView prefetchDataSource 新增的API
針對self-sizing cells 的改進
5.?UITextContentType
在iOS 10 UITextField添加了textContentType枚舉,指示文本輸入?yún)^(qū)域所期望的語義意義。
使用此屬性可以給鍵盤和系統(tǒng)信息,關于用戶輸入的內(nèi)容的預期的語義意義。例如,您可以指定一個文本字段,用戶填寫收到一封電子郵件確認uitextcontenttypeemailaddress。當您提供有關您期望用戶在文本輸入?yún)^(qū)域中輸入的內(nèi)容的信息時,系統(tǒng)可以在某些情況下自動選擇適當?shù)逆I盤,并提高鍵盤修正和主動與其他文本輸入機會的整合。
6.?字體隨著手機系統(tǒng)字體而改變
當我們手機系統(tǒng)字體改變了之后,那我們App的label也會跟著一起變化,這需要我們寫很多代碼來進一步處理才能實現(xiàn),但是iOS 10 提供了這樣的屬性adjustsFontForContentSizeCategory來設置。因為沒有真機,具體實際操作還沒去實現(xiàn),如果理解錯誤幫忙指正。
UILabel *myLabel = [UILabel?new];?/*
? ? UIFont 的preferredFontForTextStyle: 意思是指定一個樣式,并讓字體大小符合用戶設定的字體大小。
? ?*/
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)版本方法如下
當系統(tǒng)版本到iOS10.0的時候 9.0和10.0比較的話是降序而不是升序,這樣會導致iOS10.0是最早的版本,這樣后面要走的iOS10的方法可能都不會走而出現(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)
下面這樣也不行它會永遠返回NO,substringToIndex:1在iOS 10 會被檢測成 iOS 1了,
#define isiOS10 ([[[[UIDevice currentDevice] systemVersion] substringToIndex:1] intValue]>=10)
正確的打開方式應該是:
#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輸出不相關信息
升級到Xcode8時,我們在debug的時候控制臺輸出了很長很長的信息,看著比較煩,怎么屏蔽呢?
需要edit Scheme添加一個鍵值對就ok了。
?|
?|
添加 key:?OS_ACTIVITY_MODE??value:?disable?
9.App跳轉(zhuǎn)設置
? openUrl:
? openURL: options: completionHandler:
? prefs:root=某項服務
若要跳轉(zhuǎn)系統(tǒng)設置,需先再URL type中添加一個prefs值,如下圖:
?|
10.?判斷版本方法
【【UIDevice currentDevice】systemVersion】
11.推送xcode適配開關
在targets的Capabiliies內(nèi)Push Notifications選項開關打開
?|
然后Background Modes打開如下幾個選項
?|
General內(nèi)導入UserNotifications.framework
?|
12.Xib文件
1) 使用Xcode8 打開xib文件是會出現(xiàn)“choose an initial device view”的提示,直接選擇藍色的 choose Device 就可以了。
2) 如果布局混亂,在xib的右下角更新一下,即 Update Frame。
13.代碼及API
1) UIView的代理方法可能會出現(xiàn)報錯,刪除NSError前面的 nullable就行了。
2) UIStatusBar的方法過期了,如果項目中設置了statusBar,那就像下面這樣寫:
- (UIStatusBarStyle)preferredStatusBarStyle {?
?return?UIStatusBarStyleDefault;
}
五.iOS 11.0
1.XCode9運行訪問系統(tǒng)相冊崩潰問題
現(xiàn)象:如圖保存圖片功能,在XCode9下運行會崩潰
原因:info.plist新增了權(quán)限配置
解決:info.plist新增一條權(quán)限:Privacy - Photo Library Additions Usage Description
2.無法獲取定位信息,第一次打開app也無法彈出定位權(quán)限提示框
iOS11 定位相關的權(quán)限做了更改,在iOS11上使用了新的定位權(quán)限key
解決方案:
如果原來申請的權(quán)限是始終允許NSLocationAlwaysUsageDescription,那么需要在保留原來的key的基礎上增加NSLocationWhenInUseUsageDescription和NSLocationAlwaysAndWhenInUsageDescription。
3.無線真機測試
這應該也是?xcode 9?的一個亮點吧,但是速度真的不是很干恭維的。注意手機和電腦必須在同一個局域網(wǎng)內(nèi)
首先使用手機連接xcode之后,打開?window->Devices and Simulator->勾選Show as run destination和Connect via network?,這樣就可以無線測試了,以后媽媽再也不用擔心忘記帶線了
?|
?|
iOS11UI方面的適配較多,如啟動圖、tabbar、劉海兒、導航欄、啟動圖等適配這些UI方面的適配就沒有整理了。。。。。。
六.iOS 12.0
1.代碼中判斷是否是iPhone X方法
之前很多人判斷手機是否是iPhone X的方法是根據(jù)手機尺寸來的.因為需要對劉海做特殊處理.現(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.升級Xcode10后項目報錯
項目中如果使用Cocoapods引用了第三方的庫,有可能會升級之后導致編譯失敗.
由于我項目中沒有使用cocoapods,所以沒有遇到,網(wǎng)上查了一下資料,大概是因為:
iOS 12移除了libstdc++, 用libc++替代:
多個 info.plist 會引起崩潰.
可以將多余的info.plist刪除
建議方案:
Xcode->File->Project Settings-> Build System -> Legacy Build System.
3.Multiple commands produce 'xxx/Info.plist'
升級?Xcode 10?之后,編譯之前的項目,發(fā)生編譯錯誤:?Multiple commands produce 'xxx/Info.plist'?,項目中存在重復命名的info.plist文件。
解決方案:
(I)標準方案:刪除所有重復命名的文件。
(II)臨時方案:
?xcworkspace?項目:Xcode菜單欄?File??->??Workspace Settings??->??Build System??->??Legacy Build System?;
?xcodeprj?項目: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)限控制,要獲取這些信息,需要手動為應用打開獲取WiFi信息的權(quán)限。
解決方案:
在開發(fā)者賬號中,勾選項目的?App ID?的?Access WiFi Infomation?選項;
在Xcode的?Capabilities?中,勾選項目的?Access WiFi Infomation?選項。
5.?Xcode 10?中?#import?的時候閃退或?qū)腩^文件不提示
在?Xcode 10?中出現(xiàn)輸入?#import?引入文件/類庫頭文件的時候?Xcode?閃退。或者輸入?#import?導入頭文件時不提示。
解決方案:
?xcworkspace?項目:Xcode菜單欄?File??->??Workspace Settings??->??Build System??->??Legacy Build System?;
?xcodeprj?項目:Xcode菜單欄?File??->??Project Settings??->??Build System??->??Legacy Build System?。
6.?webView?播放視頻返回后狀態(tài)欄消失
視頻播放完成主?window?成為?KeyWindow?的時候仍隱藏著?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?獲取和設置私有屬性,需要使用其它方式修改
如:
[textField setValue:[UIColor red] forKeyPath:@"_placeholderLabel.textColor"];
//替換為
textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@"輸入"attributes:@{NSForegroundColorAttributeName: [UIColor red]}];
2.黑線處理crash
之前為了處理搜索框的黑線問題會遍歷后刪除?UISearchBarBackground?,在iOS13會導致UI渲染失敗crash;解決辦法是設置?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)出來的界面,不再像之前版本是全屏的了
如果將此屬性設置為?UIModalPresentationAutomatic?,則讀取該屬性將始終返回具體的呈現(xiàn)樣式。 默認情況下,?UIViewController?將?UIModalPresentationAutomatic?解析為?UIModalPresentationPageSheet?,但是系統(tǒng)提供的子類可以將?UIModalPresentationAutomatic?解析為其他具體的呈現(xiàn)樣式。 保留?UIModalPresentationAutomatic?的分辨率供系統(tǒng)提供的視圖控制器使用。從iOS 13.0開始,在iOS上默認為?UIModalPresentationAutomatic?,在以前的版本上默認為?UIModalPresentationFullScreen?。 在所有其他平臺上,默認為?UIModalPresentationFullScreen?。
?UIModalPresentationPageSheet?就是下面的樣子
?|
知道了原因,我們做適配也簡單了,就是設置下屬性的事:
let second = SecondViewController()
second.modalPresentationStyle = .fullScreen
present(second, animated:?true, completion:?nil)
4.暗黑模式
iOS13使用暗黑模式時,UIView默認背景色會變成暗黑色。適配暗黑模式的工作量較大,改為強制使用正常模式。
處理方案:在plist文件中增加配置項UIUserInterfaceStyle,值為Light。
5.藍牙權(quán)限更新
上傳App Store時,如果引用了CoreBluetooth.framework,則需要添加描述配置?NSBluetoothAlwaysUsageDescription?,否則無法提交。舊版本的個推SDK引入時依賴CoreBluetooth,后續(xù)版本已修改不再依賴CoreBluetooth。
處理方案:檢查其他第三方庫并未依賴CoreBluetooth.framework,刪除對該庫的引用。
6.廢棄UIWebview改為WKWebView
暫時沒有強制修改,但是已經(jīng)發(fā)郵件提示,需要做一下修改,否則可能無法上架哈
7.KVC限制
在iOS13上通過KVC來修改系統(tǒng)API私有屬性時會報錯
*** 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、平時開發(fā)時注意KVC的使用
8. 第三方登錄支持蘋果登錄(Sign In with Apple)
蘋果更新了審核指南,要求所有專門使用第三方登錄的App,2020 年 4 月之前,都必須接入 Sign in with Apple。符合以下條件的App,可以不接入:
使用自建賬戶和登錄系統(tǒng);
要求用戶使用現(xiàn)有的教育或企業(yè)賬戶登錄的教育、企業(yè)或商業(yè)類應用;
使用政府或行業(yè)支持的公民身份識別系統(tǒng)或電子 ID 來驗證用戶;
應用特定于第三方服務,用戶需要使用郵箱、社交媒體或其它第三方賬戶才能訪問其內(nèi)容的應用;
9.使用MJExtension 中處理NSNull的不同
這個直接會導致Crash的在將服務端數(shù)據(jù)字典轉(zhuǎn)換為模型時,如果遇到服務端給的數(shù)據(jù)為NSNull時,
mj_JSONObject,其中 class_copyPropertyList方法得到的屬性里,多了一種EFSQLBinding類型的東西,而且屬性數(shù)量也不準確,
那就沒辦法了,
我只能改寫這個方法了,這個組件沒有更新的情況下,寫了一個方法swizzling掉把當遇到 NSNull時,直接轉(zhuǎn)為nil了。
10.WKWebView 中測量頁面內(nèi)容高度的方式變更
iOS 13以前
document.body.scrollHeight
iOS 13中
document.documentElement.scrollHeight
兩者相差55 應該是瀏覽器定義高度變了
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選項
?|
iOS 13之后以上方法獲取Wi-Fi名返回的都是固定值"WLAN",這里可能是因為蘋果保護用戶隱私而產(chǎn)生的問題,因為通過wifi信息可以定位到用戶地理位置。所以iOS13以后如果想要繼續(xù)獲取WiFi名稱,需要在調(diào)用接口前判斷用戶是否同意App使用地理位置信息??梢栽诔绦蛞粏訒r請求用戶權(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),將無法獲取當前Wi-Fi進行配置網(wǎng)絡,請前往“設置”-“****App”-“位置”進行授權(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)建的工程在低版本設備上運行黑屏
使用 Xcode 11 創(chuàng)建的工程,運行設備選擇 iOS 13.0 以下的設備,運行應用時會出現(xiàn)黑屏。這是因為 Xcode 11 默認是會創(chuàng)建通過 UIScene 管理多個 UIWindow 的應用,工程中除了 AppDelegate 外會多一個 SceneDelegate.
?|
這是為了 iPadOS 的多進程準備的,也就是說 UIWindow 不再是 UIApplication 中管理。但是舊版本根本沒有 UIScene,因此解決方案就是在 AppDelegate 的頭文件加上:
@property (strong, nonatomic) UIWindow *window;
15.NSAttributedString優(yōu)化
對于UILabel、UITextField、UITextView,在設置NSAttributedString時也要考慮適配Dark Mode,否則在切換模式時會與背景色融合,造成不好的體驗
不建議的做法
NSDictionary *dic = @{NSFontAttributeName:[UIFont systemFontOfSize:16]};
NSAttributedString *str = [[NSAttributedString alloc] initWithString:@"富文本文案"attributes:dic];
推薦的做法
// 添加一個NSForegroundColorAttributeName屬性
NSDictionary *dic = @{NSFontAttributeName:[UIFont systemFontOfSize:16],NSForegroundColorAttributeName:[UIColor labelColor]};
NSAttributedString *str = [[NSAttributedString alloc] initWithString:@"富文本文案"attributes:dic];