iOS 11推送通知应通过App Delegate还是仅用UNDelegate方法处理?
iOS 10+ 远程通知:该用哪个方法处理?
嘿,这个问题确实挺容易搞懵人的,我来给你把这两个方法的区别和适用场景掰扯清楚~
核心区分点:通知的「用途」和「用户交互」
1. UNUserNotificationCenterDelegate 的方法(userNotificationCenter(_:didReceive:withCompletionHandler:))
这个方法专门管用户和通知产生交互的场景:
- 用户点击了通知(不管App是前台、后台还是完全关闭状态,只要用户点了通知,都会触发这个方法)
- 用户在通知中心对通知做了滑动操作(比如标记已读、清除、触发自定义动作)
另外,如果你需要在App前台收到通知时自定义展示逻辑(比如不让系统弹出默认弹窗,自己在页面上展示提示),还要用到同个Delegate里的userNotificationCenter(_:willPresent:withCompletionHandler:)方法。
2. AppDelegate 的带回调方法(application(_:didReceiveRemoteNotification:fetchCompletionHandler:))
这个方法的核心作用是处理静默通知的后台数据刷新:
当你的通知带有content-available: 1标记(这是静默通知的关键标识),并且App处于后台/挂起状态时,系统会悄悄唤醒App,让你在这个方法里做数据拉取、本地缓存更新这类操作,最后必须调用fetchCompletionHandler告诉系统任务结果(是拿到新数据了、失败了还是没数据)。
如果你的App需要兼容iOS 9及以下版本,这个方法也会处理普通通知的接收,但在iOS 10+里,普通通知的用户交互逻辑已经完全交给UNDelegate了。
实际开发中怎么选?
- 要是你需要响应用户对通知的操作(比如点击通知跳转到详情页),或者要自定义前台通知的展示,选UNUserNotificationCenterDelegate的方法。
- 要是你需要利用静默通知在后台同步数据,选AppDelegate那个带回调的方法。
- 很多时候你得同时实现这两个方法——比如静默通知既要刷新数据,又要在数据更新后触发通知提醒;或者用户点击普通通知后,你需要先补拉最新数据再跳转页面。
给你贴两个简单的代码示例参考:
处理用户点击通知(UNDelegate)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfo // 比如根据通知里的参数跳转到对应页面 if let productId = userInfo["product_id"] as? String { // 导航到商品详情页 let detailVC = ProductDetailVC(productId: productId) UIApplication.shared.keyWindow?.rootViewController?.show(detailVC, sender: nil) } completionHandler() // 必须调用,告诉系统你处理完了 }
处理静默通知后台刷新(AppDelegate)
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { // 先判断是不是静默通知 if (userInfo["content-available"] as? String) == "1" { // 执行后台数据请求 NetworkManager.fetchLatestUserData { result in switch result { case .success(let data): // 更新本地缓存 UserDefaults.standard.set(data, forKey: "latest_user_data") completionHandler(.newData) // 告诉系统拿到新数据了 case .failure: completionHandler(.failed) // 告诉系统请求失败 } } } else { // iOS10+普通通知不会走到这里,兼容旧版本可以加处理逻辑 completionHandler(.noData) } }
内容的提问来源于stack exchange,提问作者Onicha21
相关产品推荐
相关产品推荐

