iOS11.3及以上点击通知didReceiveNotification不调用问题求助
我之前也踩过iOS 11之后通知点击回调失效的坑,结合你的描述,核心问题应该是iOS 10及以上系统对通知回调机制做了更新,旧的didReceiveNotification相关方法不再被触发了。给你几个具体的排查和解决步骤:
1. 切换到iOS 10+ 新增的UserNotifications框架回调
从iOS 10开始,苹果推出了UserNotifications框架来统一管理本地和远程通知,原来UIApplicationDelegate里的旧回调方法(比如application(_:didReceiveRemoteNotification:))在用户点击通知时可能不会再被调用。你需要做这些修改:
- 在AppDelegate中遵守
UNUserNotificationCenterDelegate协议 - 在
didFinishLaunchingWithOptions里设置通知中心的代理:UNUserNotificationCenter.current().delegate = self - 实现
userNotificationCenter(_:didReceive:withCompletionHandler:)方法,这个是iOS10+专门处理通知点击的回调
2. 处理两种App状态下的通知跳转
通知点击分两种场景,你都要覆盖到:
- App完全关闭状态下启动:此时需要在
didFinishLaunchingWithOptions里读取launchOptions中的通知参数,提前处理跳转逻辑 - App后台运行状态下唤醒:此时会直接触发上面提到的UNUserNotificationCenterDelegate的回调方法
3. 示例代码参考
这里给你一段完整的适配代码(Swift为例):
import UserNotifications @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 1. 设置通知中心代理 UNUserNotificationCenter.current().delegate = self // 2. 处理从点击通知启动App的情况 if let remoteNotification = launchOptions?[.remoteNotification] as? [String: Any] { handleNotificationJump(remoteNotification) } // 其他初始化代码... return true } // MARK: - UNUserNotificationCenterDelegate // 处理通知点击(iOS10+) func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfo handleNotificationJump(userInfo) completionHandler() // 必须调用这个方法告诉系统处理完成 } // MARK: - 通用通知跳转逻辑 private func handleNotificationJump(_ userInfo: [String: Any]) { // 从userInfo中取出你的通知类型标识,比如你自定义的"notification_type"字段 guard let notifyType = userInfo["notification_type"] as? String else { return } // 获取根控制器,根据类型跳转对应页面 guard let rootVC = UIApplication.shared.keyWindow?.rootViewController else { return } switch notifyType { case "order_detail": let orderVC = OrderDetailViewController() // 根据根控制器类型选择push或present if let navVC = rootVC as? UINavigationController { navVC.pushViewController(orderVC, animated: true) } else { let nav = UINavigationController(rootViewController: orderVC) rootVC.present(nav, animated: true) } case "message_center": let msgVC = MessageCenterViewController() rootVC.present(msgVC, animated: true) default: break } } }
4. 额外注意点
- 确保你的通知payload里包含自定义的类型标识字段,这样才能区分不同的跳转逻辑
- 测试时一定要分两种状态测试:App完全关闭后点击通知,以及App在后台时点击通知
内容的提问来源于stack exchange,提问作者Deepashree Ballodi
相关产品推荐
相关产品推荐

