iOS通知清除操作异常跳转至Deeplink问题排查求助
问题根源及修复方案
核心问题点
通知类别注册完全无效
你在willPresent方法里创建UNNotificationCategory,但这个方法是通知即将展示时才触发,而且创建后根本没把这个类别注册到通知中心——等于白写了。.customDismissAction选项根本没生效,系统没法正确识别“清除通知”的动作,反而把它当成普通通知点击,触发了Deeplink跳转。通知响应逻辑顺序错误
在didReceive方法里,你先调用了handlePushNotification,不管当前是点击通知还是清除通知,都会先走Deeplink跳转逻辑。哪怕后面判断了清除动作,也已经晚了。自定义动作标识符冲突
你用系统自带的UNNotificationDismissActionIdentifier作为自定义Clear动作的标识符,这会和系统默认的取消动作逻辑冲突,导致部分设备上识别混乱。
修复步骤
1. 提前在App启动时注册通知类别
把类别注册放到didFinishLaunchingWithOptions里,这才是正确的时机:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 其他初始化代码... // 注册自定义通知类别 let clearAction = UNNotificationAction(identifier: "CLEAR_ACTION", title: "Clear", options: []) let inviteCategory = UNNotificationCategory( identifier: "INVITE_CATEGORY", actions: [clearAction], intentIdentifiers: [], options: .customDismissAction ) UNUserNotificationCenter.current().setNotificationCategories([inviteCategory]) // 其他代码... return true }
这里用自定义的"CLEAR_ACTION"作为动作ID,避免和系统默认逻辑冲突。
2. 精简willPresent方法
删掉里面创建类别的无效代码,只保留通知展示逻辑:
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.alert, .badge, .sound]) let userInfo = notification.request.content.userInfo appScreenViewModel.handlePushNotificationInApp(userInfo: userInfo) }
3. 调整didReceive的逻辑顺序
先判断动作类型,只有非清除动作才处理Deeplink:
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { MoEngage.sharedInstance().userNotificationCenter(center, didReceive: response) let actionId = response.actionIdentifier let userInfo = response.notification.request.content.userInfo // 处理清除动作:包括自定义的CLEAR_ACTION和系统滑动清除 if actionId == "CLEAR_ACTION" || actionId == UNNotificationDismissActionIdentifier { // 只清除当前通知,别删所有通知 UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [response.notification.request.identifier]) } else { // 只有普通点击或其他自定义动作才触发Deeplink appScreenViewModel.handlePushNotification(userInfo: userInfo) } completionHandler() }
4. 确认Payload匹配
你的推送Payload里category是"INVITE_CATEGORY",和注册的类别ID一致,这个保持不变即可。
内容的提问来源于stack exchange,提问作者ferryawijayanto
相关产品推荐
相关产品推荐

