当前位置: 代码迷 >> 综合 >> iOS13 适配
  详细解决方案

iOS13 适配

热度:36   发布时间:2024-01-04 16:11:56.0

KVC 限制

iOS13 以后已经不能肆无忌惮的通过 KVC 来修改一些没有暴露出来的属性了。

*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Access to xxx's _xxx ivar is prohibited. This is an application bug'

已知:

// UITextField 的 _placeholderLabel
[textField setValue:[UIColor xxx] forKeyPath:@"_placeholderLabel.textColor"];// UISearchBar 的 _searchField
[searchBar valueForKey:@"_searchField"];
复制代码

模态弹出默认交互改变

/*Defines the presentation style that will be used for this view controller when it is presented modally. Set this property on the view controller to be presented, not the presenter.If this property has been set to UIModalPresentationAutomatic, reading it will always return a concrete presentation style. By default UIViewController resolves UIModalPresentationAutomatic to UIModalPresentationPageSheet, but other system-provided view controllers may resolve UIModalPresentationAutomatic to other concrete presentation styles.Defaults to UIModalPresentationAutomatic on iOS starting in iOS 13.0, and UIModalPresentationFullScreen on previous versions. Defaults to UIModalPresentationFullScreen on all other platforms.*/
@property(nonatomic,assign) UIModalPresentationStyle modalPresentationStyle API_AVAILABLE(ios(3.2));
复制代码

iOS 13presentViewController 默认有视差效果,模态出来的界面现在默认都下滑返回。 一些页面必须要点确认才能消失的,需要适配。如果项目中页面高度全部是屏幕尺寸,那么多出来的导航高度会出现问题。

// Swift
self.modalPresentationStyle = .fullScreen// Objective-C
self.modalPresentationStyle = UIModalPresentationFullScreen;
复制代码

UISegmentedControl 默认样式改变

默认样式变为白底黑字,如果设置修改过颜色的话,页面需要修改

UITabbar 层次发生改变,无法通过设置 shadowImage去掉上面的线

可以参考 腾讯 QMUIKit 里面的实现

App启动过程中,部分View可能无法实时获取到frame

可能是为了优化启动速度,App 启动过程中,部分View可能无法实时获取到正确的frame

// 只有等执行完 UIViewController 的 viewDidAppear 方法以后,才能获取到正确的值,在viewDidLoad等地方 frame Size 为 0,例如:[[UIApplication sharedApplication] statusBarFrame];
复制代码

标记为 API_DEPRECATED 部分类被移除

  • MPMoviePlayerController ==> AVPlayerViewController
  • UISearchDisplayController ==> UISearchController
*** 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.'
复制代码

DeviceToken 获取

DeviceToken 获取到的格式发生变化

#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);
}
复制代码

参考:developer.umeng.com/docs/66632/…

CNCopyCurrentNetworkInfo 变化

iOS13 以后只有开启了 Access WiFi Information capability,才能获取到 SSID 和 BSSID

 An app that fails to meet any of the above requirements receives the following return value:- An app linked against iOS 12 or earlier receives a dictionary with pseudo-values. In this case, the SSID is Wi-Fi (or WLAN in the China region), and the BSSID is 00:00:00:00:00:00.
- An app linked against iOS 13 or later receives NULL.
复制代码

参考:CNCopyCurrentNetworkInfo

即将废弃的 LaunchImage

iOS 8 之前我们是在 LaunchImage 来设置启动图,但是随着苹果设备尺寸越来越多,我们需要在对应的 aseets 里面放入所有尺寸的启动图,这是非常繁琐的一个步骤。因此在 iOS 8 苹果引入了 LaunchScreen.storyboard,支持界面布局用的 AutoLayout + SizeClass ,可以很方便适配各种屏幕。

需要注意的是,苹果在 Modernizing Your UI for iOS 13 section 中提到 ,从2020年4月开始,所有支持 iOS 13 的 App 必须提供 LaunchScreen.storyboard,否则将无法提交到 App Store 进行审批。

使用蓝牙需要添加权限描述

iOS 13以前,使用蓝牙时可以直接用,不会出现权限提示,iOS13以后使用就会提示。并且需要在info.plist里增加 NSBluetoothAlwaysUsageDescription

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 (developer.apple.com/documentati…).

ps:如果你的应用里面没有用到蓝牙,却提示这个问题,可以检查下 个推SDK 是否更新到最新版本

废弃UIWebview APIs

iOS 有 UIWebviewWKWebview 两种Webview。从 iOS13 开始苹果将 UIWebview 列为过期API。 目前提交苹果应用市场(App Store)会反馈以下邮件提示:

ITMS-90809: Deprecated API Usage - Apple will stop accepting submissions of apps that use UIWebView APIs .
See developer.apple.com/documentati… for more information.

fishhook 导致的Crash

如果你的APP里用到了fishhook 可能在iOS13中会crash
参见:https://github.com/facebook/fishhook/issues/61

解决方案,这样改一下先,

 

//          indirect_symbol_bindings[i] = cur->rebindings[j].replacement;if (i < ( sizeof(indirect_symbol_bindings) / sizeof(indirect_symbol_bindings[0]))) {indirect_symbol_bindings[i] = cur->rebindings[j].replacement;}

获取StatusBar

项目中通过StatusBar来获取手机当前状态,但是在iOS 13中便获取不到了,调试了一下发现是UIApplication无法获取到statusBar。

    UIApplication *app = [UIApplication sharedApplication];id _statusBar = [app valueForKeyPath:@"_statusBar"];
复制代码

于是改成如下的方式通过UIStatusBarManager获取statusBar。

    UIStatusBarManager *statusBarManager = [UIApplication sharedApplication].keyWindow.windowScene.statusBarManager;id _statusBar = nil;if ([statusBarManager respondsToSelector:@selector(createLocalStatusBar)]) {UIView *_localStatusBar = [statusBarManager performSelector:@selector(createLocalStatusBar)];if ([_localStatusBar respondsToSelector:@selector(statusBar)]) {_statusBar = [_localStatusBar performSelector:@selector(statusBar)];}}
复制代码

如果只是往StatusBar上添加View,那么到这里就已经可以获取到StatusBar了。

暗黑模式适配

https://www.jianshu.com/p/a733603747bb

  相关解决方案