1. Dark Mode
暗黑模式是iOS13的重要更新之一,隨之而來的是我們能從系統(tǒng)設(shè)置中“顯示與亮度”中選擇“淺色”、“深色”兩種模式,并且可以設(shè)置自動切換,“控制中心”亮度調(diào)節(jié)中也可直接調(diào)節(jié)。UIKit 提供新的系統(tǒng)顏色和 api 來適配不同顏色模式,xcassets 對素材適配也做了調(diào)整,具體適配可見: Implementing Dark Mode on iOS
如果不想適配深色模式,可以這樣設(shè)置
- 1、直接在項目的
plist文件中設(shè)置
<key>UIUserInterfaceStyle</key>
<string>UIUserInterfaceStyleLight</string>
- 2、在每個UIViewController或者BaseViewController中設(shè)置
if (@available(iOS 13.0, *)) {
[self setOverrideUserInterfaceStyle:UIUserInterfaceStyleLight];
} else {
// Fallback on earlier versions
}
2.私有方法 KVC 不允許使用
在 iOS 13 中不再允許使用 valueForKey、setValue:forKey: 等方法獲取或設(shè)置私有屬性,雖然編譯可以通過,但是在運(yùn)行時會直接崩潰
// 使用的私有方法
[textField setValue:UIColor_d2 forKeyPath:@"_placeholderLabel.textColor"];
textField.placeholder = placeholderStr;
崩潰信息:
// 崩潰提示信息
*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Access to UITextField's _placeholderLabel ivar is prohibited. This is an application bug'
解決方案:
NSMutableAttributedString *placeholderString = [[NSMutableAttributedString alloc] initWithString:placeholderStr
attributes:@{NSForegroundColorAttributeName:UIColor_d2}];
textField.attributedPlaceholder = placeholderString;
3.推送的 deviceToken 獲取到的格式發(fā)生變化
原本可以直接將 NSData 類型的 deviceToken 轉(zhuǎn)換成 NSString 字符串,然后替換掉多余的符號即可:
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
NSLog(@"deviceToken:%@", token);
}
在 iOS 13 中,這種方法已經(jīng)失效,NSData 類型的 deviceToken 轉(zhuǎn)換成的字符串變成了:
{length=32,bytes=0xd02daa63aade35488d1e24206f44037d...fd6b2fac80bddd2d}
需要進(jìn)行一次數(shù)據(jù)格式處理,參考友盟的做法,可以適配新舊系統(tǒng),獲取方式如下:
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
if (![deviceToken isKindOfClass:[NSData class]]) return;
const unsigned *tokenBytes = [deviceToken bytes];
NSString *token = [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:%@", token);
}
這樣就獲取到正確的 deviceToken 字符串
d02daa63aade35488d1e24206f44037dce9ece7f85adf6acfd6b2fac80bddd2d
4.控制器的 modalPresentationStyle 默認(rèn)值變了
在 iOS 13 UIModalPresentationStyle 枚舉的定義中,蘋果新加了一個枚舉值:
typedef NS_ENUM(NSInteger, UIModalPresentationStyle) {
...
UIModalPresentationAutomatic API_AVAILABLE(ios(13.0)) = -2,
};
在 iOS 13 中此枚舉值直接成為了模態(tài)彈出的默認(rèn)值,因此 presentViewController 方式打開視圖是下滑返回的視差效果。如果你完全接受蘋果的這個默認(rèn)效果,那就不需要去修改任何代碼。如果你原來就比較細(xì)心,已經(jīng)設(shè)置了modalPresentationStyle 的值,那你也不會有這個影響。對于想要找回原來默認(rèn)交互的同學(xué),直接設(shè)置如下即可:
self.modalPresentationStyle = UIModalPresentationOverFullScreen;
5.MPMoviePlayerController 被棄用
在 iOS 9 之前播放視頻可以使用 MediaPlayer.framework 中的MPMoviePlayerController類來完成,它支持本地視頻和網(wǎng)絡(luò)視頻播放。但是在 iOS 9 開始被棄用,如果在 iOS 13 中繼續(xù)使用的話會直接拋出異常:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'MPMoviePlayerController is no longer available. Use AVPlayerViewController in AVKit.'
解決方案是使用 AVFoundation 里的 AVPlayer。
6.藍(lán)牙權(quán)限描述
最近一次提審被拒情況,被拒原因之一就是需要添加藍(lán)牙權(quán)限獲取描述,提交以后構(gòu)建顯示正在處理中,等幾分鐘會自動消失,構(gòu)建不成功,Apple發(fā)送郵件提示:
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
NSBluetoothAlwaysUsageDescriptionkey 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).
原因是iOS13 將廢棄 NSBluetoothPeripheralUsageDescription 替換為NSBluetoothAlwaysUsageDescription
解決方法,在 info.plist 中添加新字段
<key> NSBluetoothAlwaysUsageDescription </key>
<string>App需要您的同意,才能訪問藍(lán)牙</string>
重新上傳即可