針對 iOS 13,蘋果作了很是大的調整,其中 Dark 模式是最新的 UI 層面可見的改變,而針對iPad推出了 iPadOS
,致使了與 iOS 的分化,同時爲了 iPad 而不得不對 iOS 一樣作出的改變,好比一個應用支持多 window 顯示。因此,每一年 WWDC 後,由於每一個應用的狀況不同,使用的API各不相同,致使適配的工做沒法一致,你們遇到的坑不相同,因此,把你們遇到的問題都彙總起來,那就是必定有做用,這就是本文的初心。ios
iOS13最大的特色是帶來了暗黑模式,可是若是不適配的話,可能會出現該是黑色的地方用了白色了,該是白色的地方是黑色了,看不到了,怎麼關掉呢?git
#if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
if(@available(iOS 13.0,*)){
self.window.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
}
#endif
複製代碼
Info.plist
添加key: UIUserInterfaceStyle
設置爲強制用暗黑模式(Dark
)或白天模式(Light
)<key>UIUserInterfaceStyle</key>
<string>UIUserInterfaceStyleLight</string>
複製代碼
目前蘋果尚未公佈何時強制適配黑夜模式。按以前的官方的文章實際上是沒有強制要求全部App都適配,由於有些App確實可能很難適配。github
若是您須要更多時間調節 app 在深色模式中的外觀,或您的 app 不適用於深色模式,您可進一步瞭解如何停用深色模式。web
ITMS-90809: Deprecated API Usage - Apple will stop accepting submissions of apps that use UIWebView APIs . See developer.apple.com/documentati… for more information.swift
UIWebView iOS 2.0–12.0 Deprecated Mac Catalyst 13.0–13.0 Deprecatedwindows
2019-12月更新瀏覽器
The App Store will no longer accept new apps using UIWebView as of April 2020 and app updates using UIWebView as of December 2020.bash
蘋果已經強制要求2020年4月新應用不能再使用 UIWebView,2020年12月全部應用更新不能在使用 UIWebView。微信
iOS13後,Prensent方式彈出頁面時,默認的模式變爲了UIModalPresentationAutomatic,這樣的方式也挺好的,動畫也好看,自帶關閉,只要下拉就關閉頁面了,這樣的動畫方式下,以前會出現的《UITabBar在iPhoneX等Push時顯示錯亂問題》 的問題也不存在了。 但有的時候,咱們不但願使用這個樣式,好比須要用戶不能關閉的:app
只要指定彈出頁的 modalPresentationStyle
屬性,注意是要Present的頁面:
UIViewController *vc = [[UIViewController alloc] init];
vc.modalPresentationStyle = UIModalPresentationFullScreen;
[self.navigationController presentViewController:vc animated:YES completion:nil];
複製代碼
iOS 13起,app的 info.plist裏增長
<key>NSBluetoothAlwaysUsageDescription</key>
<string>咱們要一直使用您的藍牙,具體作什麼別問我</string>
複製代碼
iOS 13之前
document.body.scrollHeight
複製代碼
iOS 13中
document.documentElement.scrollHeight
複製代碼
二者相差55 應該是瀏覽器定義高度變了
以前的 UIActivityIndicatorView 有三種 style 分別爲 whiteLarge
, white
和 gray
,如今所有廢棄。 增長兩種 style 分別爲 medium
和 large
,指示器顏色用 color
屬性修改。
去掉原來 .default
.lightContent
,改成 :
![iOS13-Status Bar.png](github.com/iHTCboy/iGa… Bar.png)
Sign In with Apple will be available for beta testing this summer. It will be required as an option for users in apps that support third-party sign-in when it is commercially available later this year. Apple登陸將於今年夏天進行beta測試。對於支持第三方用戶登陸的應用中,apple 登陸將在今年晚些時候上市銷售時做爲選項。
經過API來獲取到諸如用戶姓名這樣的信息,可是最爲關鍵的userIdentifier
則是毫無規律可言的(至少在咱們開發者看來),而這個userIdentifier
則爲同一個開發者帳號下的全部app中保持有且僅有一個。 另外,apple 登陸是支持跨平臺,安卓和 windows 的 web 頁面中使用 apple id 登陸受權。
注意: Sign In with Apple 須要用戶開啓了兩步認證,若是沒有開啓則會在第一次使用時提示開啓,不開啓將沒法使用。
另外,蘋果登陸按鈕有所要求, 詳細見 Sign In with Apple - Sign In with Apple - Human Interface Guidelines - Apple Developer
2019年9月更新
4.8 經過 Apple 登陸 若是 app 專門使用第三方或社交登陸服務 (例如,Facebook 登陸、Google 登陸、經過 Twitter 登陸、經過 LinkedIn 登陸、經過 Amazon 登陸或微信登陸) 來對其進行設置或驗證這個 app 的用戶主賬戶,則該 app 必須同時提供「經過 Apple 登陸」做爲等效選項。用戶的主賬戶是指在 app 中創建的、用於標識身份、登陸和訪問功能和相關服務的賬戶。 在如下狀況下,不要求提供「經過 Apple 登陸」選項:
- 您的 app 僅使用公司自有的賬戶設置和登陸系統。
- 您的 app 是一款教育、企業或商務 app,要求用戶使用現有的教育或企業賬戶登陸。
- 您的 app 使用政府或行業支持的公民身份系統或電子身份證來鑑定用戶身份。
- 您的 app 是特定第三方服務的客戶端,用戶須要使用他們的郵件、社交媒體或其餘第三方賬戶直接登陸才能訪問內容。
iOS 13 經過 KVC 方式修改私有屬性,有 Crush 風險,謹慎使用! iOS13 之後已經不能肆無忌憚的經過 KVC 來修改一些沒有暴露出來的屬性了。會崩潰: 'Access to UITextField's _placeholderLabel ivar is prohibited. This is an application bug'
已知:
// UITextField的placeholder的顏色
[textField setValue:[UIColor xxx] forKeyPath:@"_placeholderLabel.textColor"];
// UISearchBar 的 _searchField
[searchBar valueForKey:@"_searchField"];
複製代碼
修改以下:
NSMutableAttributedString *placeholderString = [[NSMutableAttributedString alloc] initWithString:placeholder attributes:@{NSForegroundColorAttributeName : self.placeholderColor}];
_textField.attributedPlaceholder = placeholderString;
複製代碼
默認樣式變爲白底黑字,若是設置修改過顏色的話,頁面須要修改。另外UI樣式發生了變化。
多是爲了優化啓動速度(或者留海屏緣由),App 啓動過程當中,部分View可能沒法實時獲取到正確的frame
// 只有等執行完 UIViewController 的 viewDidAppear 方法之後,才能獲取到正確的值,在viewDidLoad等地方 frame Size 爲 0,例如:
[[UIApplication sharedApplication] statusBarFrame];
複製代碼
在使用到MPMoviePlayerController的地方,直接拋了異常:
'MPMoviePlayerController is no longer available. Use AVPlayerViewController in AVKit.'
複製代碼
替代方案就是AVKit裏面的那套播放器
這個很重要!!! 可能大多數使用第三方推送的童鞋都不會注意到這個問題,通常如今的第三方推送都是將DeviceToken原始數據丟進去,具體的解析都是第三方內部處理,因此,這些第三方解析DeviceToken的方式正確的話,那就毫無問題。若是大家是經過這種方式來獲取DeviceToken,那你須要注意了。(這個坑也是多年前埋下的,不少文章介紹的也是下面這個方法,不規範的作法早晚要還的),以下:
NSString *dt = [deviceToken description];
dt = [dt stringByReplacingOccurrencesOfString: @"<" withString: @""];
dt = [dt stringByReplacingOccurrencesOfString: @">" withString: @""];
dt = [dt stringByReplacingOccurrencesOfString: @" " withString: @""];
複製代碼
這段代碼運行在 iOS 13 上已經沒法獲取到準確的DeviceToken字符串了,iOS 13 經過[deviceToken description]獲取到的內容已經變了。
{length = 32, bytes = 0x778a7995 29f32fb6 74ba8167 b6bddb4e ... b4d6b95f 65ac4587 }
複製代碼
解決方法,fb sdk 中:
+ (NSString *)hexadecimalStringFromData:(NSData *)data
{
NSUInteger dataLength = data.length;
if (dataLength == 0) {
return nil;
}
const unsigned char *dataBuffer = data.bytes;
NSMutableString *hexString = [NSMutableString stringWithCapacity:(dataLength * 2)];
for (int i = 0; i < dataLength; ++i) {
[hexString appendFormat:@"%02x", dataBuffer[i]];
}
return [hexString copy];
}
複製代碼
友盟推送的解決方法
- (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);
}
}
複製代碼
這2個方法那個好? 根據蘋果文檔 application:didRegisterForRemoteNotificationsWithDeviceToken::
友盟的兼容方案並不嚴謹,蘋果說tokens長度可變,建議不要硬編碼!!
更多參考: iOS13 PKPushCredentials broken |Apple Developer Forums facebook-objc-sdk/FBSDKInternalUtility.m 【公告】iOS 13正式發佈後對U-Push的影響 NotificationCenter · Issue #23 · ChenYilong/iOS13AdaptationTips
從 iOS 8 的時候,蘋果就引入了 LaunchScreen,咱們能夠設置 LaunchScreen來做爲啓動頁。固然,如今你還可使用LaunchImage來設置啓動圖。不過使用LaunchImage的話,要求咱們必須提供各類屏幕尺寸的啓動圖,來適配各類設備,隨着蘋果設備尺寸愈來愈多,這種方式顯然不夠 Flexible。而使用 LaunchScreen的話,狀況會變的很簡單, LaunchScreen是支持AutoLayout+SizeClass的,因此適配各類屏幕都不在話下。
注意: 從2020年4月開始,全部使⽤ iOS13 SDK 的 App 將必須提供 LaunchScreen,LaunchImage即將退出歷史舞臺。
再補充一點,在使用 LaunchScreen的時候,裏面用到的圖片資源,最好別放在 xcassets 裏面,否則在你修改圖片後,你會發現真機上並不會生效。
iOS 支持多界面同時運行多個用戶界面。 root view controller 的 view superview 也不直接是 UIWindow 了:
iOS 13 能夠多windows窗口,把ui相關的生命週期單獨到 SceneDelegate:
若是實現 SceneDelegate 那麼iOS 13會調整 SceneDalegate, 若是不實現,就會使用 AppDelegate。iOS 12 如下仍是調用 AppDelegate:
@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));
複製代碼
獲取keyWindow 使用 [UIApplicatoin sharedApplication].keyWindow 狀況就有多種:
沒有了 keyWindow,那之後怎麼得到當前激活中的 window 呢?能夠看看這裏:How to resolve: 'keyWindow' was deprecated in iOS 13.0
具體調整可參見官方WWDC: Architecting Your App for Multiple Windows - WWDC 2019 - Videos - Apple Developer
在 Xcode 11以前的文檔:
// value is an NSString containing the bundle ID of the originating application
在 Xcode 11後變爲:
// value is an NSString containing the bundle ID of the originating application; non-nil if the originating application and this application share the same team identifier
官方在線文檔:
UIApplicationOpenURLOptionsSourceApplicationKey A key that contains the bundle ID of the app that sent the open-URL request to your app.
The value of this key is an NSString object containing the bundle ID of the app that made the request. If the request originated from another app belonging to your team, UIKit sets the value of this key to the ID of that app. If the team identifier of the originating app is different than the team identifier of the current app, the value of the key is nil.
在 iOS 13 中,非同一開發者帳號(team identifier)的App,在 iOS 13 經過 URL Scheme
打開App裏,在代理方法 - (BOOL)application: openURL: options:
中將UIApplicationOpenURLOptionsSourceApplicationKey
返回爲nil
,也就是說,再也拿不到原App的 bundle ID,關於這個你們都說是蘋果爲了解決隱私問題?
對於開發者來講,若是有使用到 SourceApplication 字段,只能在 iOS 13以上調整本身的業務邏輯。
這些都只是常見和彙總網上你們遇到的狀況,還有不少細節上,針對 iOS13 須要你們細調,這些年下來,iOS各系統版本以前的突變不少,固然這樣也有好處,好比 WKWebview 支持 iOS 8.0 + , SFSafariViewController 支持 iOS 9.0+,慢慢地,不少更好的 API 你們均可以使用,拋棄舊的接口,兼容新的接口,這樣的工做,可預見將來一直會這樣,誰叫咱們是 API 使用者!努力成爲提供 API man 吧!