iOS 13适配
9月20号iOS 13 已正式发布,第一时间更新了最新系统,网上对其用户体验上的新特性的描述也很多,而对于开发者来说,更需要关注的是新系统在 API 层面做了哪些改动,对我们现有的代码产生什么影响,需要做什么样的适配。
本文主要列举了一些需要开发者注意的地方,不一定项目中都有涉及到相关发生变化的东西,但仍需注意。
一、 iOS 13 支持的机型
•iPhone X、iPhone XR、iPhone XS、iPhone XS Max
•iPhone 8、iPhone 8 Plus
•iPhone 7、iPhone 7 Plus
•iPhone 6s、iPhone 6s Plus
•iPhone SE
•iPod touch (第七代)
二、 适配要求
Starting April, 2020, all iOS apps submitted to the App Store will need to be built with the iOS 13 SDK or later. They must also support the all-screen design of iPhone XS Max or the 12.9-inch iPad Pro (3rd generation), or later.
根据官网的说法,2020年4月之后所有提交到 App Store 的应用必须使用 iOS 13 以上的 SDK 进行编译,并要求屏幕尺寸支持 iPhone Xs Max 和 12.9 寸 iPad Pro。
三、具体适配清单
1、 Dark Mode
Dark Mode(暗黑模式)是苹果在iOS13推出的新特性。使用iOS13及更高版本的系统的iOS 设备,可以使用暗黑模式。在暗黑模式下,系统会采用较暗的视图控件。开发者在开发过程中需要对视图控件进行相应暗模式的适配。
适配原理:
1.将同一个资源,创建出两种模式的样式。系统根据当前选择的样式,自动获取该样式的资源
2.每次系统更新样式时,应用会调用当前所有存在的元素调用对应的一些重新方法,进行重绘视图,可以在对应的方法做相应的改动
如果不打算适配 Dark Mode,可以强行关闭暗黑模式
if(@available(iOS 13.0, *)){
[self setOverrideUserInterfaceStyle:UIUserInterfaceStyleLight];
}
不过即使设置了颜色方案,系统自带的申请各个权限的弹窗还是会依据系统的颜色进行显示,自己创建的提示弹窗 UIAlertController则不会。
对于暗黑模式,如果项目中重新对各个控件设置过背景色,那么即使开启暗黑模式,也不会对控件的背景色有影响;如果未重新设置过背景色,那么APP里的控件就会根据系统的显示模式而显示相应的颜色,此时需要适配暗黑模式,否则有些控件显示就会异常。
2、Sign In with Apple
在 iOS 13 中苹果推出一种在 App 和网站上快速、便捷登录的方式: Sign In With Apple。这是 iOS 13 新增的功能,因此需要使用 Xcode 11 进行开发。关于应用是否要求接入此登录方式,苹果在 App Store 应用审核指南 中提到:
Apps that exclusively use a third-party or social login service (such as Facebook Login, Google Sign-In, Sign in with Twitter, Sign In with LinkedIn, Login with Amazon, or WeChat Login) to set up or authenticate the user’s primary account with the app must also offer Sign in with Apple as an equivalent option.
如果应用使用了第三方或社交账号登录服务(如Facebook、Google、Twitter、LinkedIn、Amazon、微信等)来设置或验证用户的主账号,就必须把 Sign In With Apple 作为同等的选项添加到应用上。
如果是下面这些类型的应用则不需要添加:
•仅仅使用公司内部账号来注册和登录的应用;
•要求用户使用现有的教育或企业账号进行登录的教育、企业或商务类型的应用;
•使用政府或业界支持的公民身份识别系统或电子标识对用户进行身份验证的应用;
•特定第三方服务的应用,用户需要直接登录其邮箱、社交媒体或其他第三方帐户才能访问其内容。
另外需要注意,关于何时要求接入 Sign In With Apple,苹果在 News and Updates 中提到:
Starting today, new apps submitted to the App Store must follow these guidelines. Existing apps and app updates must follow them by April 2020.
现有应用和应用更新须在 2020 年 4 月前完成接入。
这部分目前还未看到有APP做这一条的适配,对于我们自己自身的APP我觉得暂时也不急于做,可以先看看其他APP具体如何做,然后参考参考,再制定具体的方案。
3、模态弹出视图的显示问题
一般打开新页面会采用push的方式,某些临时页面会采用模态视图present的方式,iOS13后模态出新页面的时候会出现页面从导航栏下开始显示的情况,主要是因为之前对UIViewController里面的一个属性,即modalPresentationStyle(该属性是控制器在模态视图时将要使用的样式)没有设置需要的类型。
在iOS13中modalPresentationStyle的默认改为UIModalPresentationAutomatic,而在之前默认是UIModalPresentationFullScreen。所以如果想显示样式和以前的保持一致,需要手动设置modalPresentationStyle为UIModalPresentationFullScreen
这个属性不受Xcode版本的影响,只要是iOS13系统,采用present的方式打开页面却没有设置modalPresentationStyle为UIModalPresentationFullScreen的话,就会有这个显示问题
4、不允许使用KVC进行对私有属性进行获取或者修改
iOS13中通过KVC方式来获取私有属性,有Carsh风险,尽量避免使用.比如我们常用的UITextFiled和UISearchController等。尽量不要使用valueForKey、setValue: forKeyPath: 等方法获取或设置私有属性,虽然编译可以通过,但是在运行时会直接崩溃。比如访问 UISearchBar 的 _searchField:
UITextField *textField = [searchBar valueForKey:@"_searchField"];//崩溃
[textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];//崩溃
5、推送的 deviceToken 获取到的格式发生变化
系统返回deviceToken的方法是- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
由此可见,返回的是NSData类型的deviceToken。如果需要把NSData类型的deviceToken转换成字符串类型,原本只需要用系统方法转换,然后替换掉多余的符号即可:
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSString *token = [deviceToken description];
for (NSString *symbol in @[@" ", @"<", @">", @"-"]) {
token = [token stringByReplacingOccurrencesOfString:symbol withString:@""];
}
NSLog(@"deviceToken:%@", token);
}
但在 iOS 13 中,这种方法已经失效,NSData类型的 deviceToken 转换成的字符串变成了:
{length = 32, bytes = 0xd7f9fe34 69be14d1 fa51be22 329ac80d … 5ad13017 b8ad0736 } `
解决方案:
需要进行一次数据格式处理,获取方式如下:
#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);
}
项目中用到deviceToken的场景是注册极光推送,而极光推送注册的API使用的是NSData类型的deviceToken,所以并不需要客户端做类型转换处理,目前相关的推送SDK也未有iOS13兼容的更新提示,后续是否需要升级推送SDK,还需继续关注。
6、 iOS13以后将不再继续支持UIWebView
UIKIT_EXTERN API_DEPRECATED("No longer supported; please adopt WKWebView.", ios(2.0, 12.0)) API_UNAVAILABLE(tvos, macos) @interface UIWebView : UIView <NSCoding, UIScrollViewDelegate>
1
在 iOS 13 后,官方将UIWebView的支持的系统范围定格在了iOS 2.0 ~ iOS 12.0,建议开发者用WKWebView对UIWebView进行适配。目前,网上有人提到,如果开发者将包含 UIWebView api 的应用更新上传到 App Store 审核后,其将会收到包含 ITMS-90809 信息的回复邮件,提示你在下一次提交时将应用中 UIWebView 的 api 移除。但是并不会影响当次的审核,下次再提交如果还是有UIWebView还是会继续发邮件提醒你更换成WKWebView。
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… 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
解决方案
用 WKWebView替代UIWebView,确保所有 UIWebView 的 api 都要移除,如果需要适配 iOS 7 的可以通过 openURL 的方式在 Safari 打开。
7、UISearchDisplayController被废弃
在iOS 8 之前,在 UITableView 上添加搜索框可以采用 UISearchBar + UISearchDisplayController的组合方式,而在 iOS 8 之后,苹果就已经推出了 UISearchController 来代替这个组合方式。在 iOS 13 中已经不支持UISearchDisplayController,如果还继续使用 UISearchDisplayController 会直接导致崩溃,崩溃信息如下:
*** 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.'
1
解决方案
使用UISearchController替换 UISearchBar + UISearchDisplayController 的组合方案。
8、 MPMoviePlayerController 被弃用
在 iOS 9 之前播放视频可以使用MediaPlayer.framework中的MPMoviePlayerController类来完成,它支持本地视频和网络视频播放。但是在 iOS 9 开始被弃用,如果在 iOS 13 中继续使用的话会直接抛出异常:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'MPMoviePlayerController is no longer available. Use AVPlayerViewController in AVKit.'
1
解决方案
使用AVFoundation 里的AVPlayer 作为视频播放控件。
9、蓝牙权限字段更新导致审核失败
For apps with a deployment target of iOS 13 and later, use NSBluetoothAlwaysUsageDescription instead.
1
在 iOS 13 中,苹果将原来蓝牙申请权限用的 NSBluetoothPeripheralUsageDescription字段,替换为 NSBluetoothAlwaysUsageDescription 字段。
如果还是以旧的字段提交审核,将会收到包含 ITMS-90683 的邮件
解决方案
官方文档提到:
For deployment targets earlier than iOS 13, add both NSBluetoothAlwaysUsageDescription and NSBluetoothPeripheralUsageDescription to your app’s Information Property List file.
1
所以只要在Info.plist 中把两个字段都加上即可。
10、 LaunchImage 被弃用
iOS 有两种设置启动图的方式,一种是LaunchImage,一种是LaunchScreen。采用LaunchImage设置启动图的话需要根据不同的机型设计相应尺寸的启动图,随着苹果设备屏幕尺寸越多,所需要的启动图就越多,这种启动图的设置方式就会显得不够智能;LaunchScreen只要一张图片,系统会自动适配,其采用的是AutoLayout+SizeClass的方式,可以自动适配各种屏幕。
苹果在 Modernizing Your UI for iOS 13 section 中提到 ,从2020年4月开始,所有支持 iOS 13 的 App 必须提供LaunchScreen.storyboard,否则将无法提交到 App Store 进行审核。
11、 UISegmentedControl 默认样式改变
默认样式变为白底黑字,如果设置修改过颜色的话,页面需要修改。
原本设置选中颜色的tintColor 已经失效,新增了selectedSegmentTintColor 属性用以修改选中的颜色。
12、 Xcode 11 创建的工程在低版本设备上运行黑屏
使用 Xcode 11 创建的工程,运行设备选择 iOS 13.0 以下的设备,运行应用时会出现黑屏。这是因为 Xcode 11 默认是会创建通过UIScene管理多个 UIWindow 的应用,工程中除了AppDelegate外会多一个SceneDelegate,
SceneDelegate是为了 iPadOS 的多进程准备的,但是旧版本根本没有UIScene。
解决方案
在 AppDelegate 的头文件加上:
@property (strong, nonatomic) UIWindow *window;
13、 StatusBar 与之前版本不同
目前状态栏也增加了一种模式,由之前的两种,变成了三种, 其中default由之前的黑色内容,变成了会根据系统模式,自动选择当前展示lightContent还是darkContent
14、 TabBar 选中文字颜色变成系统默认蓝色
在iOS13系统中,跳转到二级页面再返回一级页面时,TabBar的选中项的文字颜色会变成系统默认的蓝色。主要是由于tincolor影响了 ,通过重新设置默认颜色即可
if (@available(iOS 13.0, *)) {
self.tabBar.unselectedItemTintColor = THEMEBLUECOLOR;
} else {
// Fallback on earlier versions
}
以上是综合各个资料及项目中遇到的整理的iOS13适配点,从20号发布iOS13.0正式版到现在,截止目前已经推出了iOS13.1.3版本,关于iOS13的适配仍需持续关注。
————————————————
版权声明:本文为CSDN博主「WScarlett」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/fhsahfihf/article/details/102592861