点击通知打开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
相关产品推荐
相关产品推荐

