You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS Swift:AppDelegate中self.window?.rootViewController报错 不删SceneDelegate如何实现推送跳转

适配SceneDelegate的推送跳转实现方案

崩溃原因

iOS 13 引入多场景管理机制后,窗口实例的管理逻辑从AppDelegate迁移到了SceneDelegate,默认情况下AppDelegate的window属性不会被初始化,所以你直接访问self.window?.rootViewController会得到nil值,强制解包就会触发Swift runtime failure: force unwrapped a nil value崩溃。

解决代码

不需要删除SceneDelegate相关文件,只需要修改根控制器的获取逻辑,从当前活跃的场景中取窗口实例即可,修改后的完整代码如下:

func userNotificationCenter(_ center: UNUserNotificationCenter,
                            didReceive response: UNNotificationResponse,
                            withCompletionHandler completionHandler: @escaping () -> Void) {
    print("userNotificationCenter didReceive")
    defer {
        completionHandler()
    }
    guard response.actionIdentifier == UNNotificationDefaultActionIdentifier else {
        return
    }

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let destinationVC = storyboard.instantiateViewController(withIdentifier: "MyPage") as! PageViewController

    // 适配Scene机制,从活跃场景中获取根导航控制器
    guard let windowScene = UIApplication.shared.connectedScenes
            .filter({ $0.activationState == .foregroundActive || $0.activationState == .foregroundInactive })
            .first as? UIWindowScene,
          let navigationController = windowScene.windows.first?.rootViewController as? UINavigationController else {
        return
    }

    navigationController.pushViewController(destinationVC, animated: false)
    UNUserNotificationCenter.current().removeAllDeliveredNotifications()
}

特殊场景适配

  • 如果你的App根控制器是UITabBarController,需要先拿到UITabBarController实例,再取当前选中的导航控制器执行跳转
  • 如果当前页面有模态弹出的控制器,需要先遍历找到最顶层的展示控制器,再执行push或者present操作

内容的提问来源于stack exchange,提问作者Punreach Rany

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 18:24:04