已关闭通知权限,App处于前台时仍收到推送通知问题咨询
核心原因
iOS的通知权限(设置里的开关)仅控制系统是否自动展示通知弹窗、角标或播放提示音,但不会阻止application(_:didReceiveRemoteNotification:fetchCompletionHandler:)方法的触发。只要推送payload被苹果APNs服务器正常送达,且App处于前台运行状态,这个方法就会被调用——这就是你关闭权限后仍能收到推送数据的原因。
从你的日志可以看到推送payload包含完整的aps.alert字段:
AppDelegate::application(_:didReceiveRemoteNotification:fetchCompletionHandler:)[L:------------------didReceiveRemoteNotification [AnyHashable("aps"): { alert = { body = "Push payload body"; subtitle = "Test push notification"; title = "Push Hero"; }; }]------------------]
解决办法
在didReceiveRemoteNotification方法中主动检查当前App的通知授权状态,仅当用户允许通知时,才处理alert内容的展示逻辑;若权限已关闭,则直接忽略相关内容。
示例代码(Swift):
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { UNUserNotificationCenter.current().getNotificationSettings { settings in // 仅当授权状态为允许或临时允许时,才处理通知内容 guard settings.authorizationStatus == .authorized || settings.authorizationStatus == .provisional else { completionHandler(.noData) return } // 解析并处理推送的alert内容(如需自定义展示) if let aps = userInfo["aps"] as? [String: Any], let alertDict = aps["alert"] as? [String: String] { let title = alertDict["title"] ?? "" let subtitle = alertDict["subtitle"] ?? "" let body = alertDict["body"] ?? "" // 自定义弹窗逻辑示例 DispatchQueue.main.async { let alert = UIAlertController(title: title, message: "\(subtitle)\n\(body)", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "确定", style: .default)) application.keyWindow?.rootViewController?.present(alert, animated: true) } } completionHandler(.noData) } }
额外说明
如果你的推送属于静默推送(payload包含content-available: 1且无alert字段),无论通知权限状态如何,didReceiveRemoteNotification都会被触发,这是iOS用于后台数据同步的正常机制。
内容的提问来源于stack exchange,提问作者Nguyen Huu

