iOS应用关闭时点击通知无法获取userInfo的问题求助
解决iOS App关闭状态下点击本地通知无法触发回调、获取userInfo的问题
我太懂这种挫败感了——本地通知调度和存储userInfo都正常,偏偏App彻底关闭时点击通知,对应的处理逻辑完全没反应,连UNUserNotificationCenter的回调都不触发,userInfo更是拿不到。我之前做项目时也踩过一模一样的坑,咱们从几个关键环节排查解决:
1. 确保UNUserNotificationCenter代理设置正确
这是最容易忽略的点:必须在请求通知权限之前,把AppDelegate设置为UNUserNotificationCenter的代理,否则系统无法把通知事件传递给你的回调方法。
在didFinishLaunchingWithOptions里按这个顺序写:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 第一步:设置代理,一定要在请求权限前做! UNUserNotificationCenter.current().delegate = self // 第二步:请求通知权限 let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound] UNUserNotificationCenter.current().requestAuthorization(options: authOptions) { granted, error in if let error = error { print("请求通知权限失败:\(error.localizedDescription)") } } return true }
2. 检查代理方法的完整实现
要确保你实现了正确的代理方法,尤其是didReceive response的签名不能写错,还要记得调用completionHandler——系统会等待这个回调,不调用的话可能导致后续逻辑异常。
建议用extension把代理方法抽出来,代码更清晰:
@available(iOS 10.0, *) extension AppDelegate: UNUserNotificationCenterDelegate { // 可选:App前台时弹出通知的处理逻辑 func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { // 允许前台显示通知 completionHandler([.alert, .sound, .badge]) } // 核心:点击通知后的处理(无论App是前台、后台还是关闭状态都会触发) func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { // 在这里拿到userInfo let userInfo = response.notification.request.content.userInfo print("获取到的userInfo:\(userInfo)") // 写你的业务逻辑,比如跳转到指定页面、处理数据等 // 务必调用这个方法,告诉系统你已经处理完通知事件 completionHandler() } }
3. 确认本地通知的userInfo设置正确
有时候不是回调的问题,而是创建本地通知时没正确把userInfo塞进通知内容里。检查你的通知创建代码:
func scheduleLocalNotification() { let content = UNMutableNotificationContent() content.title = "测试通知" content.body = "点击查看详情" // 正确设置userInfo content.userInfo = ["targetPage": "DetailViewController", "itemId": "12345"] // 设置触发条件(比如5秒后触发) let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false) // 创建通知请求,唯一标识符建议用业务相关的ID let request = UNNotificationRequest(identifier: "local_notification_12345", content: content, trigger: trigger) // 添加通知到调度中心 UNUserNotificationCenter.current().add(request) { error in if let error = error { print("添加本地通知失败:\(error.localizedDescription)") } } }
4. 兜底:在didFinishLaunchingWithOptions中处理启动事件
当App完全关闭时,点击通知启动App,除了代理回调,还可以在didFinishLaunchingWithOptions里拿到通知信息做兜底处理,避免极端情况漏处理:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 检查是否是通过点击本地通知启动的App if let notification = launchOptions?[.notification] as? UNNotification { let userInfo = notification.request.content.userInfo print("从启动参数拿到的userInfo:\(userInfo)") // 在这里做初始化时的业务处理 } // 其他初始化代码... return true }
按照这几个步骤检查下来,基本就能解决App关闭状态下点击通知无法触发回调、获取userInfo的问题了。
内容的提问来源于stack exchange,提问作者Rafaela Lourenço
相关产品推荐
相关产品推荐

