iOS 13適配-我遇到的坑

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 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).

原因是iOS13 將廢棄 NSBluetoothPeripheralUsageDescription 替換為NSBluetoothAlwaysUsageDescription

解決方法,在 info.plist 中添加新字段

<key> NSBluetoothAlwaysUsageDescription </key>
<string>App需要您的同意,才能訪問藍(lán)牙</string>

重新上傳即可

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • App Programming Guide for iOS翻譯 https://developer.apple.c...
    鋼鉄俠閱讀 1,247評論 0 1
  • 妹子一直說,想讀書,卻沒讀成,為什么呢? 主要原因是沒行動,說歸說,沒有真的去說,說了也等于白說。 任何一件事,想...
    文子灣閱讀 193評論 0 1
  • 明月多情應(yīng)笑我,笑我如今。辜負(fù)春心,獨(dú)自閑行獨(dú)自吟。 近來怕說當(dāng)時事,結(jié)遍蘭襟。月淺燈深,夢里云歸何處尋? 深夜的...
    3a87c8175f0a閱讀 773評論 1 4
  • 【shape】 definition: to influence the way that a person, i...
    Mia_m閱讀 285評論 0 0
  • 相信大家都聽說過吸引力法則,用官方定義就是指:“同頻共振,同質(zhì)相吸?!边@八個字的意思是說:同樣頻率的東西會共振,同...
    素說閱讀 1,305評論 0 1

友情鏈接更多精彩內(nèi)容