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

iOS中如何修改本地/推送通知的点击与长按交互行为

iOS中如何修改本地/推送通知的点击与长按交互行为

嘿,这个需求确实有点反常规,但完全可以实现!我来给你拆解具体步骤:

第一步:创建并配置通知内容扩展(实现点击通知显示交互预览)

首先你需要一个通知内容扩展(UNNotificationContentExtension),这是实现交互式通知的核心,用来展示你想要的预览和交互控件。

  • 打开Xcode,点击File -> New -> Target,选择Notification Content Extension,命名后完成创建(记得激活这个Target的签名)。
  • 打开扩展的Info.plist,找到NSExtensionAttributes节点,添加/修改以下配置:
    • UNNotificationExtensionCategory:设置一个自定义类别ID,比如ReverseNotificationCategory(后面注册通知时要对应上)
    • UNNotificationExtensionDefaultContentHidden:设为YES,这样默认的通知文本会被隐藏,点击通知直接显示你的扩展界面
    • UNNotificationExtensionInitialContentSizeRatio:可以设为1.0,让扩展界面占满通知区域

第二步:在主APP中注册自定义通知类别

在主APP的启动代码里(比如AppDelegate的didFinishLaunchingWithOptions或SceneDelegate的scene(_:willConnectTo:options:)),注册我们的自定义通知类别,同时添加一个“打开APP”的快捷动作:

func setupNotificationCategory() {
    let center = UNUserNotificationCenter.current()
    
    // 创建「打开APP」的快捷动作,设置为前台触发
    let openAppAction = UNNotificationAction(
        identifier: "OpenAppAction",
        title: "打开应用",
        options: [.foreground] // 点击后直接打开APP到前台
    )
    
    // 关联我们的自定义类别和动作
    let reverseCategory = UNNotificationCategory(
        identifier: "ReverseNotificationCategory",
        actions: [openAppAction],
        intentIdentifiers: [],
        options: []
    )
    
    // 注册类别
    center.setNotificationCategories([reverseCategory])
}

第三步:拦截默认点击行为,让点击停留在扩展界面

默认情况下,用户点击通知会直接打开APP,我们需要在主APP的通知响应方法里拦截这个行为:
在AppDelegate或SceneDelegate中实现UNUserNotificationCenterDelegate的方法:

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    // 判断是否是默认的通知点击动作
    if response.actionIdentifier == UNNotificationDefaultActionIdentifier {
        // 不执行打开APP的逻辑,让通知中心保持显示扩展界面
        completionHandler()
        // 如果你不想让APP被唤醒到后台,可以在这里做额外处理,比如直接返回
        return
    }
    
    // 如果是点击了「打开APP」的快捷动作,交给系统默认处理(打开APP)
    if response.actionIdentifier == "OpenAppAction" {
        completionHandler()
        return
    }
    
    // 其他动作的处理逻辑(如果有的话)
    completionHandler()
}

第四步:处理长按通知的逻辑

iOS系统的长按通知本身是用来唤起通知的交互预览和快捷动作的,我们没法直接把长按映射成“打开APP”,但可以优化体验:

  • 当用户长按通知时,系统会自动显示我们之前配置的「打开APP」快捷动作,用户点击这个动作就能直接打开APP。
  • 如果你想要更接近“长按直接打开APP”的体验,可以在通知扩展的界面里添加一个长按手势识别器,当用户在扩展界面上长按的时候,调用extensionContext?.open(_:completionHandler:)来打开主APP:
// 在通知扩展的ViewController里添加长按手势
override func viewDidLoad() {
    super.viewDidLoad()
    let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress))
    view.addGestureRecognizer(longPressGesture)
}

@objc private func handleLongPress() {
    // 打开主APP,替换成你的APP自定义URL Scheme
    if let url = URL(string: "yourappscheme://") { 
        extensionContext?.open(url, completionHandler: nil)
    }
}

注意:这里需要在主APP的Info.plist里配置自定义URL Scheme,比如yourappscheme,这样扩展才能通过URL唤起主APP。

第五步:发送通知时关联自定义类别

不管是本地通知还是远程推送,都需要在payload里指定我们的自定义类别,并且开启可变内容:

  • 本地通知示例:
let content = UNMutableNotificationContent()
content.title = "测试通知"
content.body = "点击查看交互,长按打开APP"
content.categoryIdentifier = "ReverseNotificationCategory"
content.mutableContent = true // 必须开启,才能加载通知扩展

let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
let request = UNNotificationRequest(identifier: "TestReverseNotification", content: content, trigger: trigger)

UNUserNotificationCenter.current().add(request)
  • 远程推送Payload示例(JSON格式):
{
    "aps": {
        "alert": {
            "title": "测试通知",
            "body": "点击查看交互,长按打开APP"
        },
        "category": "ReverseNotificationCategory",
        "mutable-content": 1
    }
}

这样配置后,就能实现你要的效果:点击通知直接显示交互式扩展界面,长按通知(或在扩展界面上长按)可以打开主APP啦!

备注:内容来源于stack exchange,提问作者iOSCoder

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 10:28:12