SwiftUI之app的生命周期

在 SwiftUI之前,我们管理 app 的生命周期使用AppDelegate,这在使用 UIKit 开发时是非常常见的。在 iOS 13.0 之后,对于 SwifUI 的 app 可以使用AppDelegateSceneDelegate来管理 app 的生命周期。

1
2
3
4
5
6
7
8
9
10
@main
struct AppLifeycleApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate

var body: some Scene {
WindowGroup {
ContentView()
}
}
}

AppleDelegate:

1
2
3
4
5
6
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
print("启动")
return true
}
}

在上面的代码中使用了@UIApplicationDelegateAdaptor包装器。如果还需要使用SceneDelegate来调用更多的生命周期函数,可以先定义一个SceneDelegate的类:

1
2
3
4
5
6
7
8
9
class SceneDelegate: NSObject,UIWindowSceneDelegate {
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let _ = (scene as? UIWindowScene) else { return }
}

func sceneDidEnterBackground(_ scene: UIScene) {
print("场景进入后台")
}
}

然后在AppDelegate中添加下面这个函数,让它和SceneDelegate进行关联:

1
2
3
4
5
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
let sceneConfig: UISceneConfiguration = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
sceneConfig.delegateClass = SceneDelegate.self
return sceneConfig
}

需要注意的是,但我们使用AppDelegate来管理 app 的生命周期时,需要针对不同的平台进行判断。相反,使用后面的这种方式则不用。

Note

If you enable scene support in your app, iOS always uses your scene delegates in iOS 13 and later. In iOS 12 and earlier, the system uses your app delegate.

iOS 14之后,SwiftUI 中提供了一种新的方式来管理 app 的生命周期:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@main
struct AppLifeycleApp: App {
@Environment(\.scenePhase) var scenePhase

var body: some Scene {
WindowGroup {
ContentView()
.onChange(of: scenePhase, {
switch scenePhase {
case .background:
print("进入后台")
case .inactive:
print("不活跃")
case .active:
print("活跃")
@unknown default:
print("默认")
}
})
}
}
}

这里,我们是直接使用Environment中的scenePhase来获取当前 app 的状态。

参考文章: Managing your app’s life cycle