如何实现 UI 状态恢复

用户自然而然地会在他们的设备上进行多任务处理。无论是在 App 间切换,还是使用“侧拉”或“分屏浏览”将 iPad 上的 App 组合使用,或者是为同一 App 创建多个窗口。它们都应该能够从中断的地方继续——而 UI 状态恢复则是实现这种体验的核心部分。

当你的 App 退出视图时,App 的进程通常会处于暂停状态;它不会获得更多的 CPU 时间,从而让处理器有时间执行其他任务。如果你的 App 有正在运行的后台进程,且一个活动的 App 需要的资源比当前可用资源更多,系统甚至可以终止这些后台进程。

恢复 UI 的状态是让你的 App 响应灵敏的关键部分——如果你计划在 iPadOS App 中支持多个窗口,那么状态恢复就显得尤为重要。例如,如果你有一个笔记 App,在不同的“分屏浏览”中打开了四个不同的笔记,状态恢复有助于保留每个笔记,而不是当用户打开其中一个窗口时将其返回到主屏幕。

可以把两种不同类型的场景放到后台,或中止进程。场景的状态应该被保存下来,以便之后恢复。

可以把两种不同类型的场景放到后台,或中止进程。场景的状态应该被保存下来,以便之后恢复。

认识 NSUserActivity

NSUserActivity 是目前状态恢复、UISceneUISceneDelegate 的核心部分:它提供了一种轻量级的方式来捕捉你的 App 的状态并在之后使用。它会保存视图控制器和重要视图状态的关键信息——这些信息也可以在为接力通用链接构建视图控制器时使用。

虽然你在 NSUserActivity 中存储的内容由你决定,但我们建议只收集必要的最少信息,让你的 App 能快速恢复。尝试想出最独特、最简单的方式来识别你的视图控制器,比如一个明确的标识符或 URL。包含这些信息,并确保你可以识别视图控制器在你的导航中的位置,以及内容应该怎样出现在其中。例如,当使用《Xcode》Storyboard 时,你可能希望使用恢复 ID 来存储和恢复视图控制器。

开始使用 UI 状态恢复

实现 UI 状态恢复的最佳方式是让你的 App 基于场景,这需要 iOS 13、iPadOS 13、Mac Catalyst 10.13、Apple tvOS 13 或它们的更高版本。(有关在 App 中使用场景的更多信息,请查看相关开发者文档。以下内容可以帮助你开始使用基于场景的状态恢复。

  1. 创建一个 NSUserActivity 对象来存储 App 的状态。你可以在场景委托中创建。
  2. 在这个 NSUserActivity 中,存储相关信息(如当前导航的状态和已经呈现或推送的视图控制器)以及用户的意图。
  3. 在场景委托中的 stateRestorationActivity(for:) 方法中返回到这个 NSUserActivity
你需要在每一个 UIScene 中收集正确的信息,以获知用户离开的位置。

你需要在每一个 UIScene 中收集正确的信息,以获知用户离开的位置。

如果你需要支持旧版本的 iOS、macOS 或 tvOS,你可以通过恢复类和 App 委托来使用旧版基于视图控制器的 API,来实现状态恢复。这也意味着,如果你想将你的 App 更新为采用 UIScene,以及在多个版本的 iOS 中实现 UI 状态恢复,你将需要同时实现基于场景和基于视图控制器的 API。不过,我们强烈建议构建基于场景的 UI 状态恢复。

与旧版 API 相比,现在的状态恢复采用另一种的方法来定义、存储和恢复你的 UI 状态和用户的意图。在基于场景的 App 中,你需要将 App 的生命周期和场景的生命周期中的事件分开,这意味着变化跟踪也变得不一样了。拥有多个场景意味着有更多的窗口需要跟踪,每个窗口都有独特的用户操作和导航历史。对于其中的一些窗口,你可能会根据其功能选择不恢复状态,这就要求状态恢复更加灵活,随着你对用户意图的定义变化。

在引入 UIScene 之前,每个 App 的生命周期都很单一。

在引入 UIScene 之前,每个 App 的生命周期都很单一。

如果你能将你的 App 更新为基于场景进行状态恢复,并采用 NSUserActivity,你还将能更便捷地使用诸多功能,比如“聚焦搜索”、“接力”、启用“通用链接”以及创建新的场景作为主要或辅助窗口等。此外,你还将为使用 App 的用户提供更流畅顺滑的体验。