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

点击通知打开Flutter iOS应用报错:No windows have a root view controller

解决「No windows have a root view controller, cannot save application state」错误的步骤

1. 实现通知点击回调并确保根控制器已初始化

在AppDelegate中补充UNUserNotificationCenterDelegate的通知点击处理方法,确保处理导航时根视图控制器已存在:

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    // 校验根控制器是否存在
    guard let rootVC = self.window?.rootViewController else {
        completionHandler()
        return
    }
    
    // 从通知信息中提取路由参数,通知Flutter端执行导航
    let userInfo = response.notification.request.content.userInfo
    if let route = userInfo["route"] as? String, let flutterVC = rootVC as? FlutterViewController {
        let channel = FlutterMethodChannel(name: "notification_router", binaryMessenger: flutterVC.binaryMessenger)
        channel.invokeMethod("navigateTo", arguments: ["route": route])
    }
    
    completionHandler()
}

2. 调整应用状态保存逻辑

修改状态保存的判断条件,仅在根控制器存在时允许保存状态:

override func application(_ application: UIApplication, shouldSaveSecureApplicationState coder: NSCoder) -> Bool {
    return self.window?.rootViewController != nil
}

3. 确保Flutter根控制器正确初始化

如果自动初始化逻辑失效,手动设置根控制器并激活窗口:

override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
    if #available(iOS 10.0, *) {
      UNUserNotificationCenter.current().delegate = self
    }
    GeneratedPluginRegistrant.register(with: self)
    
    // 手动校验并设置根控制器
    if self.window?.rootViewController == nil {
        let flutterVC = FlutterViewController()
        self.window?.rootViewController = flutterVC
        self.window?.makeKeyAndVisible()
    }
    
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}

4. 处理应用从通知启动的场景

在应用启动时读取启动参数中的通知信息,缓存后交给Flutter端处理:

override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
    if #available(iOS 10.0, *) {
      UNUserNotificationCenter.current().delegate = self
    }
    GeneratedPluginRegistrant.register(with: self)
    
    // 缓存启动时的通知信息
    if let notification = launchOptions?[.remoteNotification] as? [String: Any] {
        UserDefaults.standard.set(notification, forKey: "launchNotification")
        UserDefaults.standard.synchronize()
    }
    
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}

之后在Flutter初始化逻辑中读取缓存的通知信息,执行对应导航操作。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 21:20:24