iOS13适配 - SceneDelegate

借鉴:iOS 13 SceneDelegate适配

用XCode 11 创建的工程

在Xcode 11 创建的工程,运行设备选择 iOS 13.0 以下的设备,运行应用时会出现黑屏现象。

原因:

  1. Xcode 11 默认是会创建通过 UIScene 管理多个 UIWindow 的应用,工程中除了 AppDelegate 外会多一个 SceneDelegate;
   2. AppDelegate和SceneDelegate这是iPadOS带来的新的多窗口支持的结果,并且有效地将应用程序委托的工作分成两部分。

也就是说在我们用多窗口开发iPadOS中,从iOS 13开始,您的应用代表应该:

   1. 设置应用程序期间所需的任何数据。
   2. 响应任何专注于应用的事件,例如与您共享的文件。
   3. 注册外部服务,例如推送通知。
   4. 配置您的初始场景。

   相比之下,在iOS 13中的新顶级对象是一个UIWindowScene,场景代表可以处理应用程序用户界面的一个实例。因此,如果用户创建了两个显示您的应用程序的窗口,则您有两个场景,均由同一个应用程序委托支持。
   这些场景旨在彼此独立工作。因此,您的应用程序不再移动到后台,而是单个场景执行 - 用户可以将一个移动到后台,同时保持另一个打开。

我们可以看下info.plist文件和工程项目文件的变化如图:

image.png
image.png

适配方案一

如果我们不开发iPadOS多窗口APP,SceneDelegate窗口管理我们可以不需要直接删掉就好了。

  1. 删除掉info.plist中Application Scene Manifest选项,同时,文件SceneDelegate可删除可不删;
  2. appdelegate.m中UISceneSession相关代码删掉;
#pragma mark - UISceneSession lifecycle

- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options API_AVAILABLE(ios(13.0));{
    // Called when a new scene session is being created.
    // Use this method to select a configuration to create the new scene with.
    return [[UISceneConfiguration alloc] initWithName:@"Default Configuration" sessionRole:connectingSceneSession.role];
}

- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions API_AVAILABLE(ios(13.0));{
    // Called when the user discards a scene session.
    // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
    // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
  1. Appdelegate新增windows属性
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end


适配方案二

即要用iOS 13中新的SceneDelegate,又可以在iOS 13一下的设备中完美运行。那就添加版本判断,利用@available

步骤:

  1. SceneDelegate中每个方法添加 API_AVAILABLE(ios(13.0)),如下
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session 
options:(UISceneConnectionOptions *)connectionOptions
  API_AVAILABLE(ios(13.0)){

}

切记:这种方式,AppDelegate中的有关程序的一下状态的方法,iOS 13设备是不会走的,iOS13一下的是会收到事件回调的。13以上的设备会走SceneDelegate对应的方法

func applicationWillResignActive(_ application: UIApplication) {
   }
   .....
   .....
   .....
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 在Xcode 11 创建的工程,运行设备选择 iOS 13.0 以下的设备,运行应用时会出现黑屏现象。原因: Xc...
    宸瑶公主阅读 1,699评论 1 3
  • 关于资源 适用于计算机程序的资源是与程序可执行代码相关的数据文件。资源可以通过将代码之外的复杂数据集或图形内容创建...
    nicedayCoco阅读 674评论 0 0
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,136评论 1 32
  • 尊敬的山峰文龙老师,亲爱的家人们,大家好! 我是来自山峰教外教育的山峰洪霞,今天是我第30天的日精进,给大家分享我...
    洪霞张阅读 367评论 0 0
  • 【0427今日话题】 你经历过的最尴尬的时刻是什么?你是如何逃脱尴尬的? ——话题来自猫友菠萝姐姐 大学的时候社会...
    面包不打烊阅读 154评论 2 2