使用 ScenePhase 监听 App 活跃状态
了解如何使用 SwiftUI 中的 ScenePhase 环境变量来获取 App 状态,简化 UIKit 中复杂的通知代码。
在 iOS 开发中,应用会经历多种状态转换,比如从前台进入后台、从后台恢复到前台等。有时候,开发者需要监听这些状态变化,并在特定的时候执行一些特定的逻辑,比如:
- 在应用进入后台时保存用户数据: 例如保存用户填写但未提交的表单内容。
- 刷新界面内容: 当应用从后台切换到前台时,更新视图以确保数据最新。
- 读取剪切板:在恢复到前台时刷新界面或读取粘贴板数据(例如淘宝、拼多多)。
- 释放资源: 在应用即将进入后台时暂停耗时任务或释放内存。
使用 ScenePhase
可以轻松实现以上需求。
什么是 ScenePhase
ScenePhase 是 SwiftUI 中的一个环境值(Environment),在 iOS14
中引入。用于表示当前场景(Scene) 的生命周期状态。
它的状态主要包括以下三个:
- active:场景处于活跃状态,用户正在与其交互。
- inactive:场景不可交互,但还没有完全进入后台(例如收到来电时)。
- background:场景已经完全进入后台。
ScenePhase 使用方法
在 iOS14
之前,需要通过监听通知(如UIApplication.didBecomeActiveNotification
)来手动处理这些事件。
例如,下面这个代码,用过 onReceive 监听 NotificationCenter 通知,来获取 App 何时从后台转为前台:
.onReceive(
NotificationCenter.default.publisher(
for: UIApplication.didBecomeActiveNotification)
) { _ in
checkClipboardForImage()
}
使用ScenePhase
,可以让这个实现更加简单、直观:
import SwiftUI
struct ContentView: View {
@Environment(\.scenePhase) private var scenePhase
var body: some View {
Text("Hello, SwiftUI!")
.onChange(of: scenePhase) { newPhase in
switch newPhase {
case .active:
print("App is active: 恢复更新 UI")
// 在应用变为活跃状态时刷新界面
refreshUI()
case .inactive:
print("App is inactive: 暂停当前操作")
// 暂停动画或任务
pauseTasks()
case .background:
print("App is in background: 保存用户数据")
// 保存数据或释放资源
saveUserData()
default:
break
}
}
}
private func refreshUI() {
// 刷新界面逻辑
}
private func pauseTasks() {
// 暂停任务逻辑
}
private func saveUserData() {
// 保存数据逻辑
}
}
在上面的代码中,通过监听 scenePhase
的变化,可以明确应用处于哪个生命周期状态,并根据需要执行逻辑。