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

UNNotificationAction按钮不显示,参考Apple官方代码仍无效求解决

解决UNNotificationAction按钮不显示的问题

嘿,看了你的代码片段,问题很明显——你只配置了通知的基础内容和触发器,但完全没添加通知动作(Action)和对应的类别(Category),这就是按钮不显示的核心原因。iOS的通知动作必须绑定到类别里,再把类别关联到通知内容上,系统才会显示对应的按钮。

下面是修复后的完整代码,我会一步步解释关键步骤:

override func viewDidLoad() {
    super.viewDidLoad()
    
    let center = UNUserNotificationCenter.current()
    center.delegate = self
    
    // 1. 创建通知动作:每个按钮对应一个UNNotificationAction
    let acceptAction = UNNotificationAction(
        identifier: "action.accept", // 唯一标识,用于后续判断用户点击了哪个按钮
        title: "接受", // 按钮显示的文字
        options: [] // 可选参数,比如.destructive(红色按钮)、.authenticationRequired(需要解锁)
    )
    
    let declineAction = UNNotificationAction(
        identifier: "action.decline",
        title: "拒绝",
        options: .destructive
    )
    
    // 2. 创建通知类别:把动作集合起来,设置唯一的类别ID
    let category = UNNotificationCategory(
        identifier: "category.greeting",
        actions: [acceptAction, declineAction], // 包含的动作数组
        intentIdentifiers: [],
        options: []
    )
    
    // 3. 把类别注册到通知中心
    center.setNotificationCategories([category])
    
    // 请求通知权限
    center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
        print(granted ? "权限已获取" : "权限被拒绝")
        if granted {
            // 权限通过后再创建通知请求
            self.scheduleNotification()
        }
    }
}

// 单独抽离通知调度的方法,更清晰
private func scheduleNotification() {
    let center = UNUserNotificationCenter.current()
    
    // 设置通知内容
    let content = UNMutableNotificationContent()
    content.title = "Hello World"
    content.body = "My First Notification App"
    content.sound = UNNotificationSound.default()
    // 4. 关键!把通知内容和之前创建的类别绑定
    content.categoryIdentifier = "category.greeting"
    
    // 设置触发器(补全你没写完的代码,这里示例5秒后触发)
    let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
    
    // 创建通知请求
    let request = UNNotificationRequest(identifier: "notification.first", content: content, trigger: trigger)
    
    // 添加到通知中心
    center.add(request) { error in
        if let error = error {
            print("添加通知失败:\(error.localizedDescription)")
        }
    }
}

// 如果需要在APP前台也显示通知,实现这个代理方法
extension ViewController: UNUserNotificationCenterDelegate {
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        // 前台显示通知的样式,这里设置显示alert和sound
        completionHandler([.alert, .sound])
    }
    
    // 处理用户点击通知动作的逻辑
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        switch response.actionIdentifier {
        case "action.accept":
            print("用户点击了接受按钮")
        case "action.decline":
            print("用户点击了拒绝按钮")
        default:
            print("用户点击了通知本身")
        }
        completionHandler()
    }
}

关键要点总结:

  • 必须先创建UNNotificationAction定义按钮,再用UNNotificationCategory把动作分组,最后注册到通知中心。
  • 通知内容的categoryIdentifier必须和你创建的类别ID完全一致,否则系统找不到对应的动作。
  • 如果需要在APP前台显示通知,必须实现UNUserNotificationCenterDelegate的willPresent方法,并指定显示选项。
  • 别忘了处理用户点击动作的逻辑,通过didReceive response方法判断actionIdentifier来区分不同按钮。

内容的提问来源于stack exchange,提问作者Ethan Chu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:39:46