You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:55:01