iOS 13適配 適配指南
推送修改
原本可以直接將 NSData
類型的 deviceToken
轉(zhuǎn)換成 NSString
字符串,然后替換掉多余的符號(hào)即可:
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSString *token = [deviceToken description];
for (NSString *symbol in @[@" ", @"<", @">", @"-"]) {
token = [token stringByReplacingOccurrencesOfString:symbol withString:@""];
}
NSLog(@"deviceToken:%@", token);
}
復(fù)制代碼
在 iOS 13 中,這種方法已經(jīng)失效酸茴,NSData
類型的 deviceToken 轉(zhuǎn)換成的字符串變成了:
{length = 32, bytes = 0xd7f9fe34 69be14d1 fa51be22 329ac80d ... 5ad13017 b8ad0736 }
復(fù)制代碼
解決方案
需要進(jìn)行一次數(shù)據(jù)格式處理,參考友盟的做法,可以適配新舊系統(tǒng)酣藻,獲取方式如下:
#include <arpa/inet.h>
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
if (![deviceToken isKindOfClass:[NSData class]]) return;
const unsigned *tokenBytes = [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);
}
復(fù)制代碼
Xcode11 提交IAP包到開發(fā)者后臺(tái)不展示構(gòu)建版本
如果在升級(jí)Xcode11后,提交IAP包到開發(fā)者卻長(zhǎng)時(shí)間沒(méi)有展示構(gòu)建版本鳍置,去翻閱對(duì)應(yīng)的郵箱郵件可能會(huì)有如下郵件:
**ITMS-90683: Missing Purpose String in Info.plist** - Your app's code references one or more APIs that access sensitive user data. The app's Info.plist file should contain a NSBluetoothAlwaysUsageDescription key with a user-facing purpose string explaining clearly and completely why your app needs the data. Starting Spring 2019, all apps submitted to the App Store that access user data are required to include a purpose string. If you're using external libraries or SDKs, they may reference APIs that require a purpose string. While your app might not use these APIs, a purpose string is still required. You can contact the developer of the library or SDK and request they release a version of their code that doesn't contain the APIs. Learn more ([https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy).](https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy). "https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy).")
After you’ve corrected the issues, you can use Xcode or Application Loader to upload a new binary to App Store Connect.
原因:
iOS13中新增藍(lán)牙權(quán)限辽剧,需要添加對(duì)應(yīng)權(quán)限申請(qǐng)說(shuō)明。
解決方式:
target - info.plist下添加如下鍵值對(duì):
Privacy - Bluetooth Always Usage Description
: 使用用途
??止 KVC 對(duì)系統(tǒng)API私有屬性的設(shè)置
下面方式對(duì) UITextField 設(shè)置placeholder的顏色會(huì)產(chǎn)生崩潰
[_textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor”];
修改為:
[_textField setAttributedPlaceholder:<#(NSAttributedString * _Nullable)#>];
KVC獲取狀態(tài)欄(_statusBar)會(huì)導(dǎo)致崩潰
UIApplication *app = [UIApplication sharedApplication]; if ([[app valueForKeyPath:@"_statusBar"] isKindOfClass:NSClassFromString(@"UIStatusBar_Modern")]) {
NSArray *views = [[[[app valueForKeyPath:@"statusBar"] valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];
同理其他私有屬性的讀取也建議進(jìn)行修改
UITextField leftView税产、rightView
問(wèn)題:
- 在設(shè)置leftView 左按鈕時(shí)怕轿,如果使用的是UIImageView即會(huì)出現(xiàn)圖片無(wú)法按照意圖顯示的問(wèn)題偷崩。
解決:
- UIImageVIew 包一層UIView再設(shè)置給leftView 、設(shè)置leftView或rightView不要使用約束布局
問(wèn)題:
- iOS13 rightView純文本按鈕可能無(wú)法正常顯示撞羽,按鈕長(zhǎng)度變短阐斜。
解決:
- 重新修改
- (CGRect)rightViewRectForBounds:(CGRect)bounds
大小
暗黑模式適配
具體適配的文章很多,這里就不做展開了诀紊。
著重說(shuō)一點(diǎn)谒出,如果沒(méi)有需要支持的暗黑模式的需求,只需要在target 下的 info.plist中添加以下key & value
key: User Interface Style
value : Light
其他
- iOS 13 不再支持
UIApplicationExitsOnSuspend
邻奠。需要更新應(yīng)用以處理現(xiàn)代多任務(wù)處理笤喳。
iOS13 UIKit & API修改 & 一些細(xì)節(jié)
1. 新增部分Color,如下示例
@property (class, nonatomic, readonly) UIColor *systemGray2Color API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *systemGray3Color API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *systemGray4Color API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *systemGray5Color API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
@property (class, nonatomic, readonly) UIColor *systemGray6Color API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(tvos, watchos);
#pragma mark Foreground colors
/* Foreground colors for static text and related elements.
*/
@property (class, nonatomic, readonly) UIColor *labelColor API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *secondaryLabelColor API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *tertiaryLabelColor API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
@property (class, nonatomic, readonly) UIColor *quaternaryLabelColor API_AVAILABLE(ios(13.0), tvos(13.0)) API_UNAVAILABLE(watchos);
2. 根據(jù)系統(tǒng)設(shè)置 LightMode 和 DarkMode 狀態(tài)取色
UIColor *backgroundColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * traitCollection) {
self->_userInterfaceStyle = traitCollection.userInterfaceStyle;
[weakSelf performSelector:@selector(traitCollectionChanged:) withObject:traitCollection];
if (traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
return [UIColor blueColor];
}
return [UIColor yellowColor];
}];
3.UIActivityIndicatorView loading菊花修改
iOS13之前的三種樣式:
-
UIActivityIndicatorViewStyleGray
灰色 -
UIActivityIndicatorViewStyleWhite
白色 -
UIActivityIndicatorViewStyleWhiteLarge
白色(大型)
iOS13廢棄了以上三種樣式惕澎,用以下兩種樣式代替:
-
UIActivityIndicatorViewStyleLarge
(大型) -
UIActivityIndicatorViewStyleMedium
(中型)
iOS13通過(guò)color屬性設(shè)置顏色
4. statusBar修改
typedef NS_ENUM(NSInteger, UIStatusBarStyle) {
UIStatusBarStyleDefault = 0, // Automatically chooses light or dark content based on the user interface style
UIStatusBarStyleLightContent API_AVAILABLE(ios(7.0)) = 1, // Light content, for use on dark backgrounds
UIStatusBarStyleDarkContent API_AVAILABLE(ios(13.0)) = 3, // Dark content, for use on light backgrounds
UIStatusBarStyleBlackTranslucent NS_ENUM_DEPRECATED_IOS(2_0, 7_0, "Use UIStatusBarStyleLightContent") = 1,
UIStatusBarStyleBlackOpaque NS_ENUM_DEPRECATED_IOS(2_0, 7_0, "Use UIStatusBarStyleLightContent") = 2,
} API_UNAVAILABLE(tvos);
在iOS13之前有兩種狀態(tài)莉测,default
和lightContent
在iOS13 有三種狀態(tài)颜骤,default,
darkContent
和 lightContent
darkContent 對(duì)應(yīng)之前的 default
唧喉,
default 會(huì)根據(jù)情況自動(dòng)選擇 darkContent
和 lightContent
5. [UIApplication sharedApplication].keyWindow API將被棄用
@property(nullable, nonatomic,readonly) UIWindow *keyWindow API_DEPRECATED("Should not be used for applications that support multiple scenes as it returns a key window across all connected scenes", ios(2.0, 13.0));
iOS13 UIApplication keyWindow被標(biāo)記為API_DEPRECATED,
修改使用下方代碼獲取
[[[UIApplication sharedApplication] windows] objectAtIndex:0]
6. UISearchDisplayController徹底棄用忍抽,導(dǎo)致崩潰
在 iOS 8 之前八孝,我們?cè)?UITableView 上添加搜索框需要使用 UISearchBar + UISearchDisplayController 的組合方式。
在 iOS 8 之后鸠项,蘋果就已經(jīng)推出了 UISearchController 來(lái)代替這個(gè)組合方式干跛。在 iOS 13 中,如果還繼續(xù)使用 UISearchDisplayController會(huì)直接導(dǎo)致崩潰祟绊,崩潰信息如下:
Terminating app due to uncaught exception 'NSGenericException', reason: 'UISearchDisplayController is no longer supported when linking against this version of iOS. Please migrate your application to UISearchController.'
解決方法:使用UISearchController代替
7.MPMoviePlayerController 棄用
MPMoviePlayerController 在 iOS 9 開始被棄用楼入,如果在 iOS 13 中繼續(xù)使用的話會(huì)直接拋出異常:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'MPMoviePlayerController is no longer available. Use AVPlayerViewController in AVKit.'
解決辦法:使用 AVPlayer 作為視頻播放控件
8. 模態(tài)彈出默認(rèn)樣式改變 UIModalPresentationStyle
在 iOS 13,使用 presentViewController 方式打開視圖牧抽,會(huì)跟導(dǎo)航欄有部分視覺(jué)差嘉熊,如下圖
原因是:蘋果將 UIViewController 的 modalPresentationStyle 屬性的默認(rèn)值改成了新加的一個(gè)枚舉值 UIModalPresentationAutomatic,對(duì)于多數(shù) UIViewController扬舒,此值會(huì)映射成 UIModalPresentationPageSheet阐肤。
解決辦法: 可以在vcpresent之前設(shè)置modalPresentationStyle 為 UIModalPresentationFullScreen
另外,present的vc用戶下拉可以dissmiss控制器讲坎,如果不想要這效果孕惜,可以這樣設(shè)置
/*當(dāng)該屬性為 false 時(shí),用戶下拉可以 dismiss 控制器晨炕,為 true 時(shí)衫画,下拉不可以 dismiss控制器*/
xxVC.isModalInPresentation = true
還有一點(diǎn)需要注意,原來(lái)以UIModalPresentationFullScreen
樣式彈出頁(yè)面瓮栗,那么這個(gè)頁(yè)面彈出 ViewController 會(huì)依次調(diào)viewWillDisappear
和 viewDidDisappear
碧磅。然后在這個(gè)頁(yè)面被 dismiss 的時(shí)候碘箍,將他彈出的那個(gè) ViewController 的 viewWillAppear
和 viewDidAppear
會(huì)被依次調(diào)用。然而使用默認(rèn)的視差效果彈出頁(yè)面鲸郊,將他彈出的那個(gè) ViewController 并不會(huì)調(diào)用這些方法丰榴,原先寫在這四個(gè)函數(shù)中的代碼以后都有可能會(huì)存在問(wèn)題。
9.藍(lán)牙權(quán)限相關(guān)修改
升級(jí)iOS13的用戶很明顯的體驗(yàn)就是秆撮,很多APP都會(huì)申請(qǐng)藍(lán)牙權(quán)限四濒,這與本次修改有關(guān)。
在 iOS 13 中职辨,蘋果將原來(lái)藍(lán)牙申請(qǐng)權(quán)限用的 NSBluetoothPeripheralUsageDescription
字段盗蟆,替換為 NSBluetoothAlwaysUsageDescription
字段。
For apps with a deployment target of iOS 13 and later, use NSBluetoothAlwaysUsageDescription instead.
10. iOS13徹底廢棄UIWebview
iOS13 提交APP時(shí)舒裤,會(huì)提示UIWebview為過(guò)期API喳资,會(huì)發(fā)送郵件提示你在下一次提交時(shí)將應(yīng)用中UIWebView 的 api 移除。
Dear Developer,
We identified one or more issues with a recent delivery for your app, "xxx". Your delivery was successful, but you may wish to correct the following issues in your next delivery:
ITMS-90809: Deprecated API Usage - Apple will stop accepting submissions of apps that use UIWebView APIs . See [developer.apple.com/documentati…]([https://developer.apple.com/documentation/uikit/uiwebview](https://developer.apple.com/documentation/uikit/uiwebview)
) for more information.
After you’ve corrected the issues, you can use Xcode or Application Loader to upload a new binary to App Store Connect.
Best regards,
The App Store Team
暫時(shí)沒(méi)有強(qiáng)制使用WKWebView腾供,但是在iOS13開始UIWebView已是廢棄的API仆邓,以后更高的版本中防止出現(xiàn)問(wèn)題,應(yīng)及時(shí)替換伴鳖。
11. 第三方登錄支持蘋果登錄 Sign In with Apple
在 iOS 13 中蘋果推出一種在 App 和網(wǎng)站上便捷登錄的方式: Sign In With Apple,這是 iOS 13 新增的功能节值,因此需要使用 Xcode 11 進(jìn)行開發(fā)。
2020 年 4 月之前榜聂,Apple 平臺(tái) App 需接入 Sign in with Apple
蘋果在上周更新了審核指南搞疗,加入 4.8 Sign in with Apple 一條,要求所有專門使用第三方登錄的 App须肆,都必須接入 Sign in with Apple匿乃。符合以下條件的App,可以不接入:
- 使用自建賬戶和登錄系統(tǒng)豌汇;
- 要求用戶使用現(xiàn)有的教育或企業(yè)賬戶登錄的教育幢炸、企業(yè)或商業(yè)類應(yīng)用;
- 使用政府或行業(yè)支持的公民身份識(shí)別系統(tǒng)或電子 ID 來(lái)驗(yàn)證用戶瘤礁;
- 應(yīng)用特定于第三方服務(wù)阳懂,用戶需要使用郵箱、社交媒體或其它第三方賬戶才能訪問(wèn)其內(nèi)容的應(yīng)用柜思;
12. LaunchImage 修改(iOS 7.0–13.0)
UILaunchImages has been deprecated; use Xcode launch storyboards instead. For more information on how to construct and format your launch storyboard, seeLaunch Screen
從2020年4月開始岩调,所有支持 iOS 13 的 App 必須提供 LaunchScreen.storyboard,否則將無(wú)法提交到 App Store 進(jìn)行審批赡盘。
13. UISearchBar 黑線處理導(dǎo)致崩潰
iOS13之前為了處理搜索框的黑線問(wèn)題号枕,通常會(huì)遍歷 searchBar 的 subViews,找到并刪除 UISearchBarBackground陨享。
修改為:
for (UIView *view in _searchBar.subviews.lastObject.subviews) {
if ([view isKindOfClass:NSClassFromString(@"UISearchBarBackground")]) {
view.layer.contents = nil;
break;
}
}
設(shè)置 UISearchBarBackground 的 layer.contents 為 nil葱淳。
14.狀態(tài)欄獲取方法
UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
15. TabBar紅點(diǎn)偏移處理
如果之前有通過(guò)TabBar上圖片位置來(lái)設(shè)置紅點(diǎn)位置钝腺,在iOS13上會(huì)發(fā)現(xiàn)顯示位置都在最左邊。
遍歷UITabBarButton的subViews赞厕,只有在TabBar選中狀態(tài)下才能取到UITabBarSwappableImageView艳狐。
解決辦法:通過(guò)UITabBarButton的位置來(lái)設(shè)置紅點(diǎn)的frame
16. UIScrollView 滾動(dòng)條異常偏移
添加以下代碼
#ifdef __IPHONE_13_0
if (@available(iOS 13.0, *)) {
self.automaticallyAdjustsScrollIndicatorInsets = NO;
}
#endif
17. UINavigationBar 設(shè)置按鈕邊距導(dǎo)致崩潰
從 iOS 11 開始,UINavigationBar
使用了自動(dòng)布局皿桑,左右兩邊的按鈕到屏幕之間會(huì)有 16 或 20 的邊距毫目。
為了避免點(diǎn)擊到間距的空白處沒(méi)有響應(yīng),通常做法是:定義一個(gè) UINavigationBar
子類诲侮,重寫 layoutSubviews
方法镀虐,在此方法里遍歷 subviews 獲取 _UINavigationBarContentView
,并將其 layoutMargins
設(shè)置為 UIEdgeInsetsZero
沟绪。
- (void)layoutSubviews {
[super layoutSubviews];
for (UIView *subview in self.subviews) {
if ([NSStringFromClass([subview class]) containsString:@"_UINavigationBarContentView"]) {
subview.layoutMargins = UIEdgeInsetsZero;
break;
}
}
}
復(fù)制代碼
然而刮便,這種做法在 iOS 13 中會(huì)導(dǎo)致崩潰,崩潰信息如下:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Client error attempting to change layout margins of a private view'
復(fù)制代碼
解決方案
使用設(shè)置 frame 的方式绽慈,讓 _UINavigationBarContentView
向兩邊伸展恨旱,從而抵消兩邊的邊距。
- (void)layoutSubviews {
[super layoutSubviews];
for (UIView *subview in self.subviews) {
if ([NSStringFromClass([subview class]) containsString:@"_UINavigationBarContentView"]) {
if ([UIDevice currentDevice].systemVersion.floatValue >= 13.0) {
UIEdgeInsets margins = subview.layoutMargins;
subview.frame = CGRectMake(-margins.left, -margins.top, margins.left + margins.right + subview.frame.size.width, margins.top + margins.bottom + subview.frame.size.height);
} else {
subview.layoutMargins = UIEdgeInsetsZero;
}
break;
}
}
}
18.UISegmentedControl 默認(rèn)樣式改變
默認(rèn)樣式變?yōu)榘椎缀谧志眯牛绻O(shè)置修改過(guò)顏色的話窖杀,頁(yè)面需要修改漓摩。
原本設(shè)置選中顏色的 tintColor
已經(jīng)失效裙士,新增了 selectedSegmentTintColor
屬性用以修改選中的顏色。
轉(zhuǎn)載部分 (以下轉(zhuǎn)載自知識(shí)小集)
UIKit
當(dāng)單元格突出顯示或選中時(shí)管毙,
UITableViewCell
類不再更改contentView
及其任何子視圖的backgroundColor
或opaque
屬性腿椎。如果要在contentView
內(nèi)部(包括)內(nèi)容的任何子視圖上設(shè)置不透明的backgroundColor
,則單元格突出顯示或選中時(shí)的外觀可能會(huì)受到影響夭咬。解決子視圖任何問(wèn)題的最簡(jiǎn)單方法是確保將backgroundColor
設(shè)置為 nil 或 clearColor啃炸,并且設(shè)置它們的 opaque 屬性為 false。但是卓舵,如果需要南用,您可以重寫setHighlighted:animated:
和setSelected:animated:
方法,以便在移動(dòng)到突出顯示的狀態(tài)和選定狀態(tài)時(shí)手動(dòng)更改子視圖上的這些屬性掏湾。從iOS 8開始裹虫,將
UISearchController
與 UINavigationController 一起使用需要將頂視圖控制器的definesPresentationContext
屬性設(shè)置為 true。如果不這樣做會(huì)導(dǎo)致難以檢測(cè)和調(diào)試的細(xì)微錯(cuò)誤融击。從 iOS & iPadOS 13 beta 開始,如果視圖控制器的 navigationItem 具有 non-nil 搜索控件,當(dāng)視圖控制器顯示在導(dǎo)航控制器中時(shí)陕贮,UINavigationController
會(huì)自動(dòng)將該視圖控制器的definesPresentationContext
屬性設(shè)置為 true。如果您要定位早期版本的 iOS封救,請(qǐng)?jiān)谒阉骺刂破髯優(yōu)榛顒?dòng)狀態(tài)之前設(shè)置此屬性。UIRefreshControl
類不再直接修改其滾動(dòng)視圖的contentInset
捣作。 相反誉结,它對(duì)內(nèi)容插入的調(diào)整將合并到滾動(dòng)視圖的adjustContentInset
中。 唯一的例外是當(dāng)滾動(dòng)視圖的contentInsetAdjustmentBehavior
設(shè)置為UIScrollViewContentInsetAdjustmentNever
時(shí)券躁,在這種情況下搓彻,UIRefreshControl
實(shí)例將像以前的版本一樣直接修改contentInset
。如果通過(guò)覆蓋
sizeThatFits
在 UITableView 中實(shí)現(xiàn)自調(diào)整單元格而不使用自動(dòng)布局嘱朽,則返回的高度將被解釋為單元格的 contentView 所需的高度旭贬,UITableViewCell 會(huì)自動(dòng)添加為單元格留出空間所需的任何其他高度 分隔器。如果以這種方式實(shí)現(xiàn)手動(dòng)自調(diào)整大小搪泳,則在 UITableViewCell 上調(diào)用sizeThatFits:
時(shí)稀轨,單元格的 contentView 寬度可以保證準(zhǔn)確,以便在手動(dòng)布局計(jì)算中使用岸军。Trait環(huán)境(例如視圖和視圖控制器)現(xiàn)在在初始化期間使用 traits 填充 traitCollection 屬性奋刽。這些初始特征表示特征環(huán)境在添加到層次結(jié)構(gòu)時(shí)將接收的最終特征的預(yù)測(cè)。因?yàn)樵诔跏蓟陂g填充的特征只是一個(gè)預(yù)測(cè)艰赞,它們可能與實(shí)際在層次結(jié)構(gòu)中接收的特征不同佣谐。因此,在可能的情況下方妖,您應(yīng)該等待執(zhí)行使用 traitCollection 的工作狭魂,直到視圖或視圖控制器的視圖移動(dòng)到層次結(jié)構(gòu)中 - 意味著窗口返回非零值 - 這樣您就不必丟棄任何工作,如果實(shí)際特征不同党觅,則使用預(yù)測(cè)的特征完成雌澄。使用 traitCollection 的最佳時(shí)間是在布局期間,例如 layoutSubviews杯瞻,
viewWillLayoutSubviews
或viewDidLayoutSubviews
內(nèi)部镐牺。只有當(dāng)特征值發(fā)生變化時(shí),才會(huì)調(diào)用
traitCollectionDidChange:
方法魁莉。重要的是睬涧,由于特征集合現(xiàn)在初始化為目標(biāo)層次結(jié)構(gòu)中最終特征的預(yù)測(cè),當(dāng)初始預(yù)測(cè)特征與層次結(jié)構(gòu)中的最終特征匹配時(shí)旗唁,特征環(huán)境添加到層次結(jié)構(gòu)時(shí)將不會(huì)調(diào)用traitCollectionDidChange:
畦浓。因?yàn)?traitCollectionDidChange:
旨在作為無(wú)效回調(diào)來(lái)通知您一個(gè)或多個(gè)特征已更改,請(qǐng)審核此方法的現(xiàn)有實(shí)現(xiàn)逆皮,以及 UIContentContainer 方法willTransitionToTraitCollection:withTransitionCoordinator:
宅粥,用于您可能依賴它的地方觸發(fā)初始設(shè)置。懶惰地執(zhí)行使用 traitCollection 的工作的最佳位置是在上面討論的 layoutSubviews 方法之一电谣,但請(qǐng)記住秽梅,這些布局方法在任何時(shí)候布局都會(huì)被調(diào)用抹蚀,所以一定要避免在不需要時(shí)重復(fù)工作。您現(xiàn)在可以啟用調(diào)試日志記錄企垦,以便在您自己的類上調(diào)用
traitCollectionDidChange:
或willTransitionToTraitCollection:withTransitionCoordinator:
時(shí)环壤。使用以下啟動(dòng)參數(shù)打開日志記錄:-UITraitCollectionChangeLoggingEnabled YES。您可能希望在使用此啟動(dòng)參數(shù)并從 Xcode 運(yùn)行應(yīng)用程序時(shí)暫時(shí)禁用主線程檢查程序钞诡,以避免為不相關(guān)的類添加額外的日志消息郑现。UITableViewCell 類的 contentView 屬性始終與前面和后面的相鄰附件進(jìn)行邊對(duì)邊布局。這簡(jiǎn)化了布局代碼荧降,因此想要正確的默認(rèn)偏移的開發(fā)人員不再需要將其內(nèi)容與內(nèi)容視圖邊框或布局邊距對(duì)齊接箫,具體取決于尾部是否有附件。您現(xiàn)在應(yīng)該始終在單元格內(nèi)容視圖的布局邊距上布置代碼以獲取默認(rèn)的系統(tǒng)插入朵诫。這些插入將根據(jù)單元格中可見(jiàn)的附件自動(dòng)調(diào)整辛友,以匹配系統(tǒng)的默認(rèn)間距。
您現(xiàn)在可以從創(chuàng)建 block 調(diào)用自定義初始化程序剪返,該創(chuàng)建塊通過(guò)
instantiateInitialViewController(creator:)
或instantiateViewController(identifier:creator:)
傳遞废累。這使您可以使用其他上下文和參數(shù)初始化視圖控制器,同時(shí)利用通過(guò) Interface Builder 在故事板中定義它們脱盲。自定義控制器初始化程序必須調(diào)用其 super.init(coder:) 方法并傳遞它通過(guò)創(chuàng)建塊接收的編碼器參數(shù)邑滨。
網(wǎng)絡(luò)
- 為了增強(qiáng)安全性,當(dāng)服務(wù)器發(fā)送
Content-Type:application/octet-stream
時(shí)钱反,NSURLSession 不再嗅探MIME
類型掖看。 -
NSURLRequestReloadRevalidatingCacheData
和NSURLRequestReloadIgnoringLocalAndRemoteCacheData API
現(xiàn)已可用。 - 從 iOS 13 beta 4 開始诈铛,強(qiáng)制執(zhí)行
NSMutableURLRequest
的HTTPBodyStream
屬性的 copy 操作乙各。如果在調(diào)用屬性設(shè)置器后對(duì) body 數(shù)據(jù)進(jìn)行了修改墨礁,則 HTTP 請(qǐng)求中發(fā)送的數(shù)據(jù)將不包含該更變幢竹。調(diào)用該屬性的 getter 不再返回 NSMutableData 引用,即使使用該類型的數(shù)據(jù)調(diào)用 setter 也是如此恩静。從 iOS 13 beta 5 開始焕毫,使用 iOS 12 SDK 或以前的 SDK 構(gòu)建的應(yīng)用程序使用舊版行為。 - CNCopyCurrentNetworkInfo API 返回的信息已無(wú)法反映真實(shí)情況驶乾。有關(guān)更多詳細(xì)信息邑飒,請(qǐng)參閱更新的API文檔和標(biāo)題。
- 包含 body 的 GET HTTP 方法的所有
NSURLSessionTask
實(shí)例現(xiàn)在都會(huì)拋出錯(cuò)誤NSURLErrorDataLengthExceedsMaximum
级乐。 - 刪除了對(duì)代理自動(dòng)配置(PAC)的 FTP 和文件URL方案的支持疙咸。HTTP 和 HTTPS 是 PAC 唯一支持的 URL 方案。這會(huì)影響所有 PAC 配置风科,包括但不限于使用“設(shè)置”撒轮,“系統(tǒng)偏好設(shè)置”乞旦,“配置文件”和
NSURLSession API
(如connectionProxyDictionary
和CFNetworkExecuteProxyAutoConfigurationURL
)設(shè)置的配置。 -
NSURLSession
和NSURLConnection
API 不再支持 SPDY题山。服務(wù)器應(yīng)使用 HTTP 2 或 HTTP 1.1兰粉。
音頻
- 現(xiàn)在可以在
AVAudioEngine
上啟用語(yǔ)音處理模式。 - 新的
AVAudioNode
類型可用于包裝用戶定義的 block顶瞳,以實(shí)時(shí)發(fā)送或接收數(shù)據(jù)玖姑。 - 基于
AVAudioEngine
的應(yīng)用程序可以使用一種新方法來(lái)檢索附加到AVAudioEngine
實(shí)例的所有節(jié)點(diǎn)的列表。 -
AVAudioEnvironmentNode
中的新渲染模式基于輸出設(shè)備自動(dòng)選擇最佳空間音頻渲染算法慨菱。 - 一個(gè)新的
AVAudioSession
屬性允許在會(huì)話主動(dòng)使用音頻輸入時(shí)播放系統(tǒng)聲音和觸覺(jué)焰络。 - 新的枚舉
AVAudioSessionPromptStyle
根據(jù)系統(tǒng)中的其他音頻活動(dòng)通知應(yīng)用程序應(yīng)該播放哪種語(yǔ)音提示。 -
AVAudioSessionRouteSharingPolicy
現(xiàn)在允許應(yīng)用指定路由共享策略符喝,以便其音頻和視頻路由到與AirPlay
相同的位置舔琅。 -
Audio Unit Extensions
現(xiàn)在支持所有宿主應(yīng)用程序中可用的用戶預(yù)設(shè)。 -
OpenAL
框架已棄用洲劣,出于兼容性目的暫時(shí)保留备蚓。過(guò)渡到 AVAudioEngine 以獲得 3D 音頻功能。 -
AUGraph
已被棄用囱稽,轉(zhuǎn)而支持 AVAudioEngine郊尝。 - 不推薦使用應(yīng)用間音頻。使用
Audio Units
支持此功能战惊。 - 不推薦使用基于
Carbon
的Audio Units
流昏,在將來(lái)的版本中不再支持。 - 不再支持舊版
Core Audio HAL
音頻硬件插件吞获。將音頻服務(wù)器插件用于支持音頻驅(qū)動(dòng)程序况凉。
音頻共享
- 音頻共享與 AirPods(第1代或更高版本)和 PowerBeats Pro 兼容。需要 iPhone 8 或更高版本各拷。