在iOS 13(及以后版本)上,SceneDelegate将负责AppDelegate的某些功能。 最重要的是,window(窗口)的概念已被scene(场景)的概念所代替。 一个应用程序可以具有不止一个场景,而一个场景现在可以作为您应用程序的用户界面和内容的载体(背景)。
尤其是一个具有多场景的App的概念很有趣,因为它使您可以在iOS和iPadOS上构建多窗口应用程序。 例如,文档编辑器App中的每个文本文档都可以有自己的场景。 用户还可以创建场景的副本,同时运行一个应用程序的多个实例(类似多开)。
在Xcode 11中有三个地方可以明显地看到SceneDelegate的身影:
SceneDelegate
类,其中包括我们熟悉的生命周期事件,例如active,resign和disconnect。application(_:configurationForConnecting:options:)
和 application(_:didDiscardSceneSessions:)
application:(UIApplication *)application didFinishLaunchingWithOptions
// 初始化
application:(UIApplication *)applicationDidBecomeActive
// 已经被激活
application:(UIApplication *)applicationWillResignActive
// 即将被挂起
application:(UIApplication *)applicationDidEnterBackground
// 已经进入后台
application:(UIApplication *)applicationWillEnterForeground
// 即将回到前台
application:(UIApplication *)applicationWillTerminate
// 即将被杀死
scene:(UIScene *)scene willConnectToSession
// 初始化
sceneDidBecomeActive:(UIScene *)scene
// 已经被激活
sceneWillResignActive:(UIScene *)scene
// 即将被挂起
sceneDidEnterBackground:(UIScene *)scene
// 已经进入后台
sceneWillEnterForeground:(UIScene *)scene
// 即将回到前台
sceneDidDisconnect:(UIScene *)scene
// 即将被杀死
如果你熟悉iOS 13之前的AppDelegate,这些方法看起来应该很熟悉。
willConnectTo:options
的默认实现会创建你的初始内容视图(content view) (如果你使用的是SwiftUI,就会创建ContentView),并创建一个新的UIWindow,然后设置window的rootViewController,并让这个window成为关键窗口。您可以将此窗口视为用户看到的窗口。不幸的是,事实并非如此。Windows在ios13之前就已经出现了,它们代表应用程序运行的视口(viewport)。UISceneSession控制用户看到的可见窗口,你创建的UIWindow是你的应用的容器视图(container view)。
除了设置初始视图外,还可以使用willConnectTo:options
来恢复场景UI,以防scene在过去断开连接。例如,因为它被发送到后台。你也可以读取connectionOptions
对象来查看你的scene是由于一个切换请求或者打开一个URL而创建的。
一旦你的scene连接好了,scene生命周期中的下一个方法就是 sceneWillEnterForeground。此方法在你的scene将要走上舞台时调用。这可能是当你的应用从后台过渡到前台,或者它只是第一次被激活。接下来,调用sceneDidBecomeActive
。这是你的scene设置,可视化,并准备被使用的地方。
一个更有趣的方法是sceneDidDisconnect
。当你的场景被发送到后台时,iOS可能会决定断开并清除你的场景以释放资源。这并不意味着你的应用程序被杀死或不再运行,它只是意味着传递给这个方法的场景不再活跃,并将从其会话断开。
sceneDidDisconnect
中要做的最重要的事情是放弃你不需要保留的任何资源。这些数据可以很容易地从磁盘或网络加载,也可以很容易地重新创建。但是要确保你保留了那些无法轻松重新创建的数据,比如用户在场景中提供的任何输入,这些输入在他们返回场景时仍然存在,具体的实现方法后续再深入研究。
在iOS13中AppDelegate中有两个管理Senen Session的代理函数。在您的应用创建scene(场景)后,“scene session”对象将跟踪与该场景相关的所有信息。
这两个函数是:
application(_:configurationForConnecting:options:)
, 会返回一个创建场景时需要的UISceneConfiguration对象application(_:didDiscardSceneSessions:)
, 当用户通过“应用切换器”关闭一个或多个场景时会被调用目前,SceneSession被用于指定场景,例如“外部显示” 或“ CarPlay” 。 它还可用于还原场景的状态,如果您想使用【状态还原】,SceneSession将非常有用。 状态还原允许您在应用启动之间保留并重新创建UI。 您还可以将用户信息存储到场景会话中,它是一个可以放入任何内容的字典。
application(_:didDiscardSceneSessions:)
很简单。 当用户通过“应用程序切换器”关闭一个或多个场景时,即会调用该方法。 您可以在该函数中销毁场景所使用的资源,因为不会再需要它们。
了解application(_:didDiscardSceneSessions:)
与sceneDidDisconnect(_ :)
的区别很重要,后者仅在场景断开连接时调用,不会被丢弃,它可能会重新连接。而application(_:didDiscardSceneSessions:)
发生在使用【应用程序切换器】退出场景时。
1、iOS13之前,appDelegate的职责全权处理App生命周期和UI生命周期
2、iOS13之后,appDelegate的职责是处理App生命周期和新的SceneSession生命周期。
3、所有UI生命周期交给SceneDelegate处理,appDelegate不在负责UI生命周期。