一炼七、iOS12(Xcode10)
1.1、升級Xcode10后項目報錯
不允許多個info.plist
Xcode10是默認選中的最新的New Build System(Default)
布持,在這個編譯系統(tǒng)的環(huán)境下豌拙,不允許多個info.plist
解決辦法一:(推薦)
把build system
切換到 Legacy Build System
,換言之就是切換成老的編譯系統(tǒng)题暖,就OK了按傅。Xcode->File->Project Settings-> Build System -> Legacy Build System.
解決辦法二:
刪除其他info.plist文件捉超。
iOS 12移除了libstdc++, 用libc++替代
Xcode10中l(wèi)ibstdc++相關(guān)的3個庫(libstdc++、libstdc++.6逞敷、libstdc++6.0.9)應(yīng)該都是被徹底廢棄了狂秦,如果你使用的三方庫中有依賴灌侣,請盡快和提供方溝通推捐,告知他們遷移吧。如果自己開發(fā)使用侧啼,也盡快考慮遷移的事宜吧牛柒。
1.2、iPhone XR不支持3D-Touch
OC檢測代碼
if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
}
復(fù)制代碼
swift檢測代碼
self.traitCollection.forceTouchCapability == .availible
復(fù)制代碼
二痊乾、iOS11(Xcode9)
2.1皮壁、安全區(qū)域(SafeArea)
iOS11為
UIViewController
和UIView
增加了兩個新的屬性safeAreaInsets
和safeAreaLayoutGuide
- [ ]
safeAreaInsets
適用于手動計算. - [ ]
safeAreaLayoutGuide
適用于自動布局.
UIViewController中新增:
- (void)viewSafeAreaInsetsDidChange;
UIView中新增:
- (void)viewSafeAreaInsetsDidChange;
復(fù)制代碼
在
Storyboard
使用Safe Area
最低只支持iOS9
哪审,iOS8
的用戶就要放棄了
當
UIViewController
調(diào)用- (void)viewDidLoad
時它的所有子視圖的safeAreaInsets
屬性都等于UIEdgeInsetsZero
蛾魄。
viewSafeAreaInsetsDidChange
的調(diào)用時機如下:
- [ ] 1、
viewDidLoad
- [ ] 2湿滓、
viewWillAppear
- [x] 3滴须、
viewSafeAreaInsetsDidChange
- [ ] 4、
viewWillLayoutSubviews
- [ ] 5叽奥、
viewDidAppear
只有在調(diào)用
viewSafeAreaInsetsDidChange
后扔水,才能獲得view
以及viewController
的SafeArea(UIEdgeInsets)
。因此在viewDidload
中根據(jù)SafeArea
設(shè)置界面會有問題朝氓。
iPhone X:有導(dǎo)航欄的時候可以+44
豎屏 safeAreaInsets
= (top
= 44, left
= 0, bottom
= 34, right
= 0)
橫屏 safeAreaInsets
= (top
= 0, left
= 44, bottom
= 21, right
= 44)
#import "Adaptive11VC.h"
static inline UIEdgeInsets sgm_safeAreaInset(UIView *view) {
if (@available(iOS 11.0, *)) {
return view.safeAreaInsets;
}
return UIEdgeInsetsZero;
}
@interface Adaptive11VC ()
@end
@implementation Adaptive11VC
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)testSafeArea {
UIEdgeInsets safeAreaInsets = sgm_safeAreaInset(self.view);
NSLog(@"safeAreaInsets = %@", NSStringFromUIEdgeInsets(safeAreaInsets));
}
- (void)viewSafeAreaInsetsDidChange {
[super viewSafeAreaInsetsDidChange];
[self testSafeArea];
}
@end
復(fù)制代碼
2.2魔市、UIScrollView
iOS 11廢棄了UIViewController
的automaticallyAdjustsScrollViewInsets
屬性,新增了contentInsetAdjustmentBehavior
屬性赵哲,所以當超出安全區(qū)域時系統(tǒng)自動調(diào)整了SafeAreaInsets
待德,進而影響了adjustedContentInset
,在iOS11中決定tableView
內(nèi)容與邊緣距離的是adjustedContentInset
枫夺,所以需要設(shè)置UIScrollView
的contentInsetAdjustmentBehavior
屬性将宪。
// 方式一:(不推薦)修改額外的安全區(qū)域
if (@available(iOS 11.0, *)) {
self.additionalSafeAreaInsets = UIEdgeInsetsMake(-44, 0, 0, 0);
}
else {
// Fallback on earlier versions
}
// 方式二:(推薦)設(shè)置為不自動調(diào)整
if (@available(iOS 11.0, *)) {
// 作用于指定的UIScrollView
self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
// 作用與所有的UIScrollView
UIScrollView.appearance.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
else {
self.automaticallyAdjustsScrollViewInsets = NO;
}
復(fù)制代碼
2.3、tableview問題
iOS11開始UITableView
開啟了自動估算行高筷屡,estimatedRowHeight``estimatedSectionHeaderHeight
estimatedSectionFooterHeight
三個高度估算屬性由默認的0變成了UITableViewAutomaticDimension
涧偷,如果不實現(xiàn)-tableView: viewForFooterInSection:
和 -tableView: viewForHeaderInSection:
,那么estimatedRowHeight
estimatedSectionHeaderHeight
estimatedSectionFooterHeight
三個高度估算屬性由默認的0變成了UITableViewAutomaticDimension
毙死,導(dǎo)致高度計算不對燎潮,會產(chǎn)生空白。解決方法是實現(xiàn)對應(yīng)方法或吧這三個屬性設(shè)為0扼倘。
2.4确封、LocalAuthentication 本地認證
本地認證框架提供了從具有指定安全策略(密碼或生物學(xué)特征)的用戶請求身份驗證的功能除呵。例如,要求用戶僅使用Face ID或Touch ID進行身份驗證爪喘,可使用以下代碼:
#import <LocalAuthentication/LocalAuthentication.h>
/**
檢測TouchID是否可用
*/
- (void)checkBiometrics {
LAContext *context = [[LAContext alloc] init];
BOOL success = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
error:nil];
if ( success ) {
NSLog(@"can use");
}
else {
NSLog(@"can`t use ");
}
}
/**
在驗證TouchID可用的情況下使用
*/
- (void)excuteBiometrics {
LAContext *context = [[LAContext alloc] init];
context.localizedFallbackTitle = @"自定義標題";
[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:@"為什么使用TouchID寫這里"
reply:^(BOOL success, NSError * _Nullable error) {
if ( success ) {
// 指紋驗證成功
}
else {
switch (error.code) {
case LAErrorUserFallback:{
NSLog(@"用戶選擇輸入密碼");
break;
}
case LAErrorAuthenticationFailed:{
NSLog(@"驗證失敗");
break;
}
case LAErrorUserCancel:{
NSLog(@"用戶取消");
break;
}
case LAErrorSystemCancel:{
NSLog(@"系統(tǒng)取消");
break;
}
// 以下三種情況如果提前檢測TouchID是否可用就不會出現(xiàn)
case LAErrorPasscodeNotSet:{
break;
}
case LAErrorTouchIDNotAvailable:{
break;
}
case LAErrorTouchIDNotEnrolled:{
break;
}
default:
break;
}
}
}];
}
復(fù)制代碼
2.5颜曾、啟動圖的適配
方法一:通過LaunchScreen.storyboard方式啟動
方法二:使用Assets中的LaunchImage
- 給Brand Assets添加一張1125*2436大小的圖片
- 打開Assets.xcassets文件夾,找到Brand Assets
- 右鍵Show in Finder
- 添加一張1125*2436大小的圖片
- 修改Contents.json文件,添加如下內(nèi)容
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "2436h",
"filename" : "1125_2436.png",
"minimum-system-version" : "11.0",
"orientation" : "portrait",
"scale" : "3x"
}
復(fù)制代碼
2.6秉剑、定位相關(guān)
在 iOS 11 中必須支持
When In Use
授權(quán)模式(NSLocationWhenInUseUsageDescription
)泛豪,在 iOS 11 中,為了避免開發(fā)者只提供請求 Always 授權(quán)模式這種情況侦鹏,加入此限制诡曙,如果不提供When In Use
授權(quán)模式,那么Always
相關(guān)授權(quán)模式也無法正常使用略水。
如果要支持老版本价卤,即 iOS 11 以下系統(tǒng)版本,那么建議在 info.plist 中配置所有的 Key(即使 NSLocationAlwaysUsageDescription
在 iOS 11及以上版本不再使用):
NSLocationWhenInUseUsageDescription
NSLocationAlwaysAndWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
NSLocationAlwaysAndWhenInUseUsageDescription // 為 iOS 11 中新引入的一個 Key渊涝。
復(fù)制代碼
2.7慎璧、iOS11中 UIKit’s Bars 上的變化
三、iOS10(Xcode8)
3.1跨释、(Why胸私?Safe!)插件取消
Xcode8取消了三方插件(很多優(yōu)秀的插件煤傍,本來可以顯著提高效率)的功能盖文,使用Extension代替Xcode 8 Extension 推薦
3.2、證書問題
為了方便用戶來管理蚯姆,提供Automatically manage signing
。需要輸入開發(fā)者賬號!如果沒有賬號也沒關(guān)系郭毕,在下面也可以選擇Debug
它碎、Realease
、inHouse
模式下對應(yīng)的證書也可以扳肛!
3.3、隱私數(shù)據(jù)訪問問題
iOS10挖息,蘋果加強了對隱私數(shù)據(jù)的保護套腹,要對隱私數(shù)據(jù)權(quán)限做一個適配绪抛,iOS10調(diào)用相機,訪問通訊錄电禀,訪問相冊等都要在info.plist中加入權(quán)限訪問描述幢码,不然之前你們的項目涉及到這些權(quán)限的地方就會直接crash掉。
解決辦法: 只需要在info.plist
添加NSContactsUsageDescription
的key
, value
自己隨意填寫就可以,這里列舉出對應(yīng)的key(Source Code模式下):
<key>NSPhotoLibraryUsageDescription</key><string>App需要您的同意,才能訪問相冊</string>
<key>NSCameraUsageDescription</key><string>App需要您的同意,才能訪問相機</string>
<key>NSMicrophoneUsageDescription</key><string>App需要您的同意,才能訪問麥克風(fēng)</string>
<key>NSLocationUsageDescription</key><string>App需要您的同意,才能訪問位置</string>
<key>NSLocationWhenInUseUsageDescription</key><string>App需要您的同意,才能在使用期間訪問位置</string>
<key>NSLocationAlwaysUsageDescription</key><string>App需要您的同意,才能始終訪問位置</string>
<key>NSCalendarsUsageDescription</key><string>App需要您的同意,才能訪問日歷</string>
<key>NSRemindersUsageDescription</key><string>App需要您的同意,才能訪問提醒事項</string>
<key>NSMotionUsageDescription</key><string>App需要您的同意,才能訪問運動與健身</string>
<key>NSHealthUpdateUsageDescription</key><string>App需要您的同意,才能訪問健康更新 </string>
<key>NSHealthShareUsageDescription</key><string>App需要您的同意,才能訪問健康分享</string>
<key>NSBluetoothPeripheralUsageDescription</key><string>App需要您的同意,才能訪問藍牙</string>
<key>NSAppleMusicUsageDescription</key><string>App需要您的同意,才能訪問媒體資料庫</string>
復(fù)制代碼
隱私數(shù)據(jù) | 對應(yīng)key值 |
---|---|
相冊 | NSPhotoLibraryUsageDescription |
相機 | NSCameraUsageDescription |
麥克風(fēng) | NSMicrophoneUsageDescription |
位置 | NSLocationUsageDescription |
在使用期間訪問位置 | NSLocationWhenInUseUsageDescription |
始終訪問位置 | NSLocationAlwaysUsageDescription |
日歷 | NSCalendarsUsageDescription |
提醒事項 | NSRemindersUsageDescription |
運動與健身 | NSMotionUsageDescription |
健康更新 | NSHealthUpdateUsageDescription |
健康分享 | NSHealthShareUsageDescription |
藍牙 | NSBluetoothPeripheralUsageDescription |
媒體資料庫 | NSAppleMusicUsageDescription |
3.4尖飞、跳轉(zhuǎn)到app內(nèi)的隱私數(shù)據(jù)設(shè)置頁面
iOS 10 干掉了所有系統(tǒng)設(shè)置的 URL Scheme症副,這意味著你再也不可能直接跳轉(zhuǎn)到系統(tǒng)設(shè)置頁面(比如 WiFi、蜂窩數(shù)據(jù)葫松、定位等)瓦糕。
跳轉(zhuǎn)方式
方式一:prefs:root=某項服務(wù) 適用于 小于 iOS10的系統(tǒng); NSURL *url = [NSURL URLWithString:@"prefs:root=WIFI"];
方式二:prefs:root=bundleID 適用于 大于等于iOS8系統(tǒng)腋么,小于iOS10的系統(tǒng) NSURL *url = [NSURL URLWithString:@"prefs:root=bundleID"];
方式三:UIApplicationOpenSettingsURLString 適用于 大于等于iOS8的系統(tǒng) NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
// iOS系統(tǒng)版本 >= 10.0
{
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
}
}
return;
// iOS系統(tǒng)版本 >= 10.0
// But! 不建議這樣做哦,官方文檔中說過:
// `URL is now considered a private API and use will result in app rejection`.
// 雖然是有可能躲過蘋果的檢測亥揖,但是蘋果如果發(fā)現(xiàn)你這樣用了珊擂,app上架是有被拒的風(fēng)險的.
{
NSURL *url = [NSURL URLWithString:@"APP-Prefs:root=WIFI"];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
if (@available(iOS 10.0, *)) {
[[UIApplication sharedApplication] openURL:url
options:@{}
completionHandler:nil];
} else {
// Fallback on earlier versions
}
}
}
// iOS系統(tǒng)版本 < 10.0
{
NSURL *url = [NSURL URLWithString:@"prefs:root=WIFI"];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
}
}
復(fù)制代碼
跳轉(zhuǎn)目的地
- [x] iOS系統(tǒng)版本 <= iOS7 , 只能跳轉(zhuǎn)到 系統(tǒng)設(shè)置頁面
- [x] iOS系統(tǒng)版本 >= iOS8 ,支持跳轉(zhuǎn)到第三方應(yīng)用的設(shè)置界面中费变。使用
prefs:root=bundleID ,bundleID
是你第三方應(yīng)用工程的唯一ID - [x] iOS系統(tǒng)版本 >= iOS10摧扇,支持跳轉(zhuǎn)到自己應(yīng)用設(shè)置,不支持跳轉(zhuǎn)到系統(tǒng)設(shè)置
3.5挚歧、字體變化
蘋果的默認字體會隨著iOS系統(tǒng)版本的不同而不同扛稽,iOS10中字體變大了。導(dǎo)致了原來的顯示有問題滑负,會造成...的出現(xiàn)在张。暫時沒有好的解決辦法,需要自己在一個個適配一下矮慕!
3.6帮匾、UICollectionViewCell的的優(yōu)化
在iOS 10 之前,cell只能從重用隊列里面取出,再走一遍生命周期,并調(diào)用cellForItemAtIndexPath創(chuàng)建或者生成一個cell.
在iOS 10 中,系統(tǒng)會cell保存一段時間,也就是說當用戶把cell滑出屏幕以后,如果又滑動回來,cell不用再走一遍生命周期了,只需要調(diào)用willDisplayCell方法就可以重新出現(xiàn)在屏幕中了.
iOS 10 中,系統(tǒng)是一個一個加載cell的,二以前是一行一行加載的,這樣就可以提升很多性能;
iOS 10 新增加的Pre-Fetching預(yù)加載
3.7、UIRefreshControl
在iOS 10 中, UIRefreshControl可以直接在UICollectionView和UITableView中使用,并且脫離了UITableViewController.現(xiàn)在RefreshControl是UIScrollView的一個屬性.
3.8痴鳄、UserNotifications(用戶通知)
iOS 10所有相關(guān)通知被統(tǒng)一到了UserNotifications.framework框架中瘟斜。增加了撤銷、更新痪寻、中途還可以修改通知的內(nèi)容螺句。通知不在是簡單的文本了,可以加入視頻橡类、圖片蛇尚,自定義通知的展示等等。
iOS 10相對之前的通知來說更加好用易于管理猫态,并且進行了大規(guī)模優(yōu)化佣蓉,對于開發(fā)者來說是一件好事披摄。
iOS 10開始對于權(quán)限問題進行了優(yōu)化,申請權(quán)限就比較簡單了(本地與遠程通知集成在一個方法中)勇凭。
四疚膊、iOS9(Xcode7)
4.1、Bitcode
Xcode7 默認啟用 Bitcode虾标,但是如果我們用到的第三方庫編譯時還沒啟用 Bitcode寓盗,主工程就會編譯不過。Bitcode 是蘋果 App Thinning 的機制之一璧函,可以減少安裝包的大小傀蚌。App store 會將這個 Bitcode 編譯為可執(zhí)行的64位或32位程序。
解決辦法一: 最簡單的解決辦法是先把 Bitcode 關(guān)掉:把 Build settings - Build Options - Enable Bitcode 改為 NO蘸吓。
[圖片上傳中...(image-de80aa-1548544915565-0)]
<figcaption style="user-select: text !important; display: block; text-align: center; font-size: 1rem; line-height: 1.6; color: rgb(144, 144, 144); margin-top: 2px;"></figcaption>
解決辦法二: 移除不支持BitCode的平臺SDK善炫,或者尋找支持BitCode的替代品,或者聯(lián)系SDK方支持BitCode库继。
4.2箩艺、HTTP 請求失敗
iOS9 默認不支持 HTTP 請求,需要改用更安全的 HTTPS(默認用 TLS 1.2)宪萄。蘋果還提供了配置艺谆,使得所有安全性更低的網(wǎng)絡(luò)請求也能使用,解決方案就是在 info.plist 里面增加以下配置:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
復(fù)制代碼
如果復(fù)雜一些拜英,還可以指定白名單域名静汤,聲明所支持 TLS 的最低版本。另外需要注意的是居凶,即使寫了上述配置虫给,在 HTTPS 頁面中,HTTP 的 javascript 或 css 不會被加載排监,因為蘋果認為這降低了頁面的安全性狰右。
4.3、canOpenUrl 限制
canOpenUrl 可以用來判斷用戶是否安裝了某個 APP舆床。也許是出于用戶隱私的考慮棋蚌,iOS9 上對 canOpenUrl 做了限制,最多只能對 50 個 scheme 做判斷挨队。如果是用 Xcode7 編譯谷暮,需要在 plist 里面聲明這些 scheme,沒有聲明的會直接返回 NO:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>weixin</string>
<string>wechat</string>
</array>
復(fù)制代碼
4.4盛垦、UIStatusBar的問題
iOS9中廢棄的方法
// 修改狀態(tài)欄的樣式為白色
// 'setStatusBarStyle(_:animated:)' was deprecated in iOS 9.0: Use -[UIViewController preferredStatusBarStyle]
UIApplication.shared.setStatusBarStyle(.lightContent, animated: true)
// 隱藏狀態(tài)欄
// 'setStatusBarHidden(_:with:)' was deprecated in iOS 9.0: Use -[UIViewController prefersStatusBarHidden]
UIApplication.shared.setStatusBarHidden(true, with: .fade)
復(fù)制代碼
用下面兩個方法替換
-[UIViewController preferredStatusBarstyle]
-[UIViewController preferredStatusBarHidden]
復(fù)制代碼
參考資料:
聊聊iOS 10更新以后跳轉(zhuǎn)系統(tǒng)設(shè)置的幾種方式
iOS 10 調(diào)用系統(tǒng)"設(shè)置"里的功能(全)