用户开启推送权限后无需重启App接收通知的实现方案咨询
解决Firebase Messaging无需重启即可获取推送权限的问题
在App进入前台时调用UIApplication.shared.registerForRemoteNotifications()完全可行,这也是处理权限变更后无需重启App的标准方案。你的核心问题在于当前仅在App启动时检查权限并注册,当用户在系统设置中开启权限后返回App,没有触发重新注册的逻辑,因此必须重启才能生效。
以下是最优处理方案,结合你的代码进行修改:
核心修改思路
- 封装权限检查与注册逻辑,在App启动和进入前台时复用
- 监听App前台激活事件,每次回到前台都重新检查通知权限
- 确保权限变更后,Firebase能获取到最新的APNS Token和FCM Token
修改后的完整代码
final class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { FirebaseApp.configure() Messaging.messaging().delegate = self // 启动时执行权限检查与注册 checkNotificationAuthAndRegister(application: application) return true } // App进入前台时触发 func applicationDidBecomeActive(_ application: UIApplication) { // 每次回到前台都检查权限,确保权限变更后能立即注册 checkNotificationAuthAndRegister(application: application) } func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { // 保存device token到服务器 // 关键:将APNS Token关联到Firebase Messaging.messaging().apnsToken = deviceToken } func application(_ application: UIApplication, didFailToContinueUserActivityWithType userActivityType: String, error: Error) { print("didFailToContinueUserActivityWithType: \(error)") } // 封装权限检查与注册逻辑 private func checkNotificationAuthAndRegister(application: UIApplication) { UNUserNotificationCenter.current().getNotificationSettings { [weak self] settings in guard settings.authorizationStatus == .authorized else { return } DispatchQueue.main.async { application.registerForRemoteNotifications() // 主动刷新FCM Token,确保权限变更后获取最新值 Messaging.messaging().token(completion: { token, error in if let error = error { print("FCM Token刷新失败: \(error.localizedDescription)") } else if let token = token { self?.saveFCMToken(token) } }) } } } // 统一处理FCM Token保存 private func saveFCMToken(_ token: String) { // 这里写入保存FCM token到服务器的逻辑 } } // MARK: - MessagingDelegate extension AppDelegate: MessagingDelegate { func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { guard let token = fcmToken else { return } saveFCMToken(token) } }
关键修改点说明
- 复用权限检查逻辑:封装
checkNotificationAuthAndRegister方法,避免启动和前台激活时重复写代码 - 监听前台激活事件:通过
applicationDidBecomeActive触发检查,确保用户从设置返回App后立即执行注册 - 关联APNS Token:在
didRegisterForRemoteNotificationsWithDeviceToken中设置apnsToken,这是Firebase关联推送通道的关键步骤(你的原代码漏掉了这一步) - 主动刷新FCM Token:权限变更后主动调用
token(completion:),确保获取最新的FCM Token,避免推送无法送达
额外注意事项
- 如果你的App使用iOS13+的SceneDelegate,需要在
sceneDidBecomeActive方法中同样调用checkNotificationAuthAndRegister,适配多场景模式 - 重复调用
registerForRemoteNotifications()是安全的,系统会自动处理重复请求,不会产生额外性能开销 - 若需要引导未授权的用户开启权限,可以在
settings.authorizationStatus == .denied时弹出提示,引导用户前往系统设置开启
内容的提问来源于stack exchange,提问作者Yuuu
相关产品推荐
相关产品推荐

