iOS App 生命周期:UIWindowSceneDelegate 流程与 UIApplicationDelegate 流程对照

82 阅读4分钟

iOS App 生命周期:UIWindowSceneDelegate 流程与 UIApplicationDelegate 流程对照

基于 Scene-based 流程与传统 UIApplicationDelegate 流程实测整理。测试机型与系统版本:iPhone 17 Pro / iOS 26.5(Scene)。图中为方法名简写。

下文「Scene 时序」对应 UIWindowSceneDelegate(及 Scene 下仍走 UIApplicationDelegate 的部分回调);「App 时序」对应未启用 Scene 时的传统 UIApplicationDelegate 流程。


第一部分:Scene 时序(UIWindowSceneDelegate)

1.1 冷启动

01-cold-start.png

普通冷启与 URL Scheme / Universal Link 时序相同,差别只在 willConnectTo 的 connectionOptions(UIScene.ConnectionOptions)及其属性:

  • 普通冷启:connectionOptions 为空(各属性均无值)
  • 点击 URL Scheme:connectionOptions.urlContexts(Set<UIOpenURLContext>),内含打开 App 的 URL
  • 点击 Universal Link:connectionOptions.userActivities(Set<NSUserActivity>),内含 Universal Link 对应的 user activity
  • 点击非静默通知:connectionOptions.notificationResponse(UNNotificationResponse),即用户点击该通知的响应对象;随后还会走 didReceive
  • 静默 Push:connectionOptions 无通知相关属性有值,随后走 didReceiveRemoteNotification

冷启时 URL Scheme / Universal Link 通常不再回调对应 Scene 入口方法,需在 willConnectTo 自行取出。

补充几点与通知相关的冷启行为:

  • 非静默通知无法在未点击时冷启唤醒app
  • 静默走 UIApplicationDelegate 的 didReceiveRemoteNotification,不走 UNUserNotificationCenter 点击回调
  • 静默 Push 冷启到 didReceiveRemoteNotification 即止,不会再调用 sceneWillEnterForeground / sceneDidBecomeActive 等前台生命周期方法

1.2 前后台与系统权限弹窗

02-foreground-background.png

1.3 非静默远程通知

03-nonsilent-push.png

  • 前台收到非静默通知:走 willPresent
    • 有无授权都会回调
    • 未授权时不进通知栏、无声音
  • 「点击通知」依赖通知栏展示,需已授权
  • 后台收到后若不点通知、只是普通回前台:只有前后台生命周期回调,无通知相关回调
  • 点击通知回前台:didReceive 发生在 sceneWillEnterForeground 之前

1.4 静默远程通知

04-silent-push.png

静默通知走 UIApplicationDelegate 的 didReceiveRemoteNotification,与 UNUserNotificationCenter 的 willPresent / didReceive 不是同一条路径。

  • 前台收到静默通知:走 didReceiveRemoteNotification(有无授权都会回调)
  • 后台收到静默通知后回前台(已授权):后台即可收到 didReceiveRemoteNotification;随后用户回前台再走前后台生命周期
  • 后台收到静默通知后回前台(未授权):时序与已授权相同,后台即可收到 didReceiveRemoteNotification,不必先回前台

1.5 后台点击 URL Scheme / Universal Link

05-deeplink-background.png

前提:App 已在后台(并非冷启)。用户点击 URL Scheme 或 Universal Link,把 App 从后台带回前台:

  • 点击 URL Scheme:openURLContexts 在 sceneWillEnterForeground 之前
  • 点击 Universal Link:continue 在 WillEnterForeground 之后、DidBecomeActive 之前

第二部分:App 时序(UIApplicationDelegate)

2.1 冷启动

01-cold-start.png

  • 非静默无法在未点击时冷启唤醒app
  • 静默 Push 冷启到 didReceiveRemoteNotification 即止,不会再调用 applicationDidBecomeActive 等前台生命周期方法

2.2 前后台与系统权限弹窗

02-foreground-background.png

2.3 非静默远程通知

03-nonsilent-push.png

  • 前台收到非静默通知:走 willPresent
    • 有无授权都会回调
    • 未授权时不进通知栏、无声音
  • 「点击通知」依赖通知栏展示,需已授权
  • 后台收到后若不点通知、只是普通回前台:只有前后台生命周期回调,无通知相关回调
  • 点击通知回前台:didReceive 发生在 applicationWillEnterForeground 之后、DidBecomeActive 之前

2.4 静默远程通知

04-silent-push.png

静默通知走 UIApplicationDelegate 的 didReceiveRemoteNotification,不走 UNUserNotificationCenter 的 willPresent / didReceive。

  • 前台收到静默通知:走 didReceiveRemoteNotification(有无授权都会回调)
  • 后台收到静默通知后回前台(已授权):后台即可收到 didReceiveRemoteNotification;随后用户回前台再走前后台生命周期
  • 后台收到静默通知后回前台(未授权):需先回前台,applicationDidBecomeActive 之后才收到 didReceiveRemoteNotification

2.5 后台点击 URL Scheme / Universal Link

05-deeplink-background.png

前提:App 已在后台(并非冷启)。用户点击 URL Scheme 或 Universal Link,把 App 从后台带回前台:

  • 点击 URL Scheme:openURL 在 WillEnterForeground 之后、DidBecomeActive 之前
  • 点击 Universal Link:continueUserActivity 同样在 WillEnterForeground 之后、DidBecomeActive 之前

第三部分:两种流程差异

左列为 UIApplicationDelegate 流程,右列为 UIWindowSceneDelegate 流程(Scene-based)。只对比非显而易见的行为差异:例如同名职责方法从 application* 换成 scene*、以及 Scene 流程多出的 willConnectTo 本身,都不单独拿出来讲。红框标出真正需要注意的不同点。

3.1 普通冷启

A-cold-start-normal.png

UIWindowSceneDelegate 冷启多一次 WillEnterForeground。

3.2 Scheme 冷启

B-cold-start-scheme.png

  • 入口参数载体不同。使用 UIWindowSceneDelegate 时,launchOptions 为空,相关参数放在 connectionOptions 中
  • UIApplicationDelegate 会调用 openURL,UIWindowSceneDelegate 不会。

3.3 Universal Link 冷启

C-cold-start-ul.png

  • 入口参数载体不同。使用 UIWindowSceneDelegate 时,launchOptions 为空,相关参数放在 connectionOptions 中
  • UIApplicationDelegate 会调用 continueUserActivity,UIWindowSceneDelegate 不会。

3.4 后台点击 Scheme

D-background-scheme.png

openURL / openURLContexts 相对 WillEnterForeground 的时机: UIApplicationDelegate 在后,UIWindowSceneDelegate 在前。

3.5 后台点击非静默通知回前台

E-background-tap-notification.png

didReceive 相对 WillEnterForeground 的时机: UIApplicationDelegate 在后,UIWindowSceneDelegate 在前。

3.6 静默 Push 冷启

F-cold-start-silent-push.png

UIApplicationDelegate 的 launchOptions 带通知信息;UIWindowSceneDelegate 的 connectionOptions 无通知信息,静默 payload 仍通过 didReceiveRemoteNotification 传入。

3.7 后台静默通知(未授权)

G-background-silent-unauthorized.png

未授权时,UIApplicationDelegate 回前台后才收到静默回调;UIWindowSceneDelegate 不用回前台,后台也能收到静默回调。

3.8 未授权时静默 Push 能否冷启

未授权时:UIApplicationDelegate 流程无法唤醒 App;UIWindowSceneDelegate 流程可以冷启唤醒,并走静默冷启链路。