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

iOS应用关闭时点击本地通知无法获取userInfo问题求助

嘿,我来帮你搞定这个App关闭时点击通知拿不到userInfo的问题!这种情况我之前也碰到过,大概率是代理设置或者方法实现的细节没处理到位,咱们一步步排查:

核心问题排查与解决步骤

1. 先确认代理的设置位置(iOS 13+关键!)

如果你的App是基于iOS 13及以上开发的,用了SceneDelegate,那一定要在SceneDelegate里设置UNUserNotificationCenter的代理,而不是只在AppDelegate里设置。因为App完全关闭后点击通知启动,系统会先走SceneDelegate的启动逻辑,代理设置晚了就会错过回调。

正确的设置方式(SceneDelegate里):

class SceneDelegate: UIResponder, UIWindowSceneDelegate, UNUserNotificationCenterDelegate {
    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // 必须在这里就设置代理,别等到后面!
        UNUserNotificationCenter.current().delegate = self
        
        // 额外:如果是点击通知直接启动App,这里也能提前拿到响应(可选)
        if let notificationResponse = connectionOptions.notificationResponse {
            self.handleNotification(response: notificationResponse)
        }
        
        guard let _ = (scene as? UIWindowScene) else { return }
    }
    
    // 你的其他代码...
}

如果是iOS 12及以下的项目,就在AppDelegate的application(_:didFinishLaunchingWithOptions:)里设置代理。

2. 完整实现代理方法,别漏了completionHandler

你提到的userNotificationCenter(_:didReceive:withCompletionHandler:)方法,必须完整实现,而且一定要调用completionHandler(),否则系统会认为你没处理完这个通知,后续逻辑可能不会正常触发。

完整的方法示例:

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    // 这里拿到你的userInfo
    let userInfo = response.notification.request.content.userInfo
    print("成功获取到userInfo: \(userInfo)")
    
    // 这里写你的业务逻辑,比如跳转对应页面、展示内容等
    handleNotification(response: response)
    
    // 必须调用这个!告诉系统你处理完了
    completionHandler()
}

// 抽离处理逻辑,代码更清晰
private func handleNotification(response: UNNotificationResponse) {
    let userInfo = response.notification.request.content.userInfo
    // 比如根据userInfo里的id跳转详情页
    if let targetId = userInfo["target_id"] as? String {
        // 执行跳转逻辑
    }
}

3. 检查通知请求的userInfo是否正确设置

有时候不是回调的问题,是你创建通知时没把userInfo正确塞进去。创建通知内容的时候要确保:

let content = UNMutableNotificationContent()
content.title = "你的通知标题"
content.body = "你的通知内容"
// 这里一定要正确设置userInfo,键值对要符合你后续解析的格式
content.userInfo = ["target_id": "12345", "type": "reminder"]

// 后续创建通知请求的代码...
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { error in
    if let error = error {
        print("添加通知失败: \(error)")
    }
}

4. 别忘了遵循协议!

不管是在SceneDelegate还是AppDelegate里,都要确保类声明时加上UNUserNotificationCenterDelegate协议,否则代理方法不会被系统调用。比如:

// SceneDelegate的正确声明
class SceneDelegate: UIResponder, UIWindowSceneDelegate, UNUserNotificationCenterDelegate { ... }

// AppDelegate的正确声明(iOS 12及以下)
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate { ... }
最后再验证一遍流程
  1. 完全关闭App(从后台划掉)
  2. 等待通知弹出,点击通知
  3. 看控制台是否打印出userInfo,同时你的业务逻辑是否触发

如果还是不行,可以检查一下通知权限是否正常授予,或者有没有其他地方覆盖了通知代理的设置。

内容的提问来源于stack exchange,提问作者Roberto Pinheiro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:30:23