如何检测iOS App是否通过推送通知启动并获取通知数据?
问题分析与解决方案
核心原因
iOS 13及后续版本中,当App处于后台状态时,通过推送通知唤醒App不会触发AppDelegate的application(_:didFinishLaunchingWithOptions:)方法。这是因为苹果引入了Scene架构,App的启动/唤醒逻辑被转移到SceneDelegate的对应方法中。
解决方案
1. 适配Scene架构(iOS 13+)
如果项目使用SceneDelegate,需在scene(_:willConnectTo:options:)中处理推送参数:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { FirebaseApp.configure() // 处理从推送唤醒的场景 if let notificationResponse = connectionOptions.notificationResponse { handleNotificationResponse(notificationResponse) } else if let launchNotification = connectionOptions.userInfo?[UIApplication.LaunchOptionsKey.remoteNotification.rawValue] as? [String: Any] { handleRemoteNotificationPayload(launchNotification) } guard let _ = (scene as? UIWindowScene) else { return } } // 自定义推送处理方法 private func handleNotificationResponse(_ response: UNNotificationResponse) { let payload = response.notification.request.content.userInfo // 在这里编写你的data payload业务逻辑 } private func handleRemoteNotificationPayload(_ payload: [String: Any]) { // 在这里编写推送data payload的处理逻辑 }
2. 兼容iOS 12及以下版本
若需支持iOS 12及更早版本,保留AppDelegate中的方法,但注意:只有App完全关闭(未在后台运行)时,点击推送才会触发application(_:didFinishLaunchingWithOptions:),此时可从launchOptions中获取推送参数:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { FirebaseApp.configure() // 处理App完全关闭时点击推送的场景 if let remoteNotification = launchOptions?[.remoteNotification] as? [String: Any] { handleRemoteNotificationPayload(remoteNotification) } return true } // 实现后台推送接收方法 func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { handleRemoteNotificationPayload(userInfo) completionHandler(.newData) }
3. Firebase Messaging补充配置
确保正确实现Firebase的推送回调,在MessagingDelegate中处理消息:
// AppDelegate中设置代理(兼容iOS12及以下) extension AppDelegate: MessagingDelegate { func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { // 处理FCM Token逻辑 } } // SceneDelegate中设置代理(iOS13+) extension SceneDelegate: MessagingDelegate { func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { // 处理FCM Token逻辑 } }
关键注意点
当App处于后台活跃(挂起)状态时,点击推送会触发UNUserNotificationCenterDelegate的userNotificationCenter(_:didReceive:withCompletionHandler:)方法,需实现该代理处理交互:
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let payload = response.notification.request.content.userInfo // 编写推送交互后的业务逻辑 completionHandler() }
内容的提问来源于stack exchange,提问作者meds
相关产品推荐
相关产品推荐

