You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Mac Catalyst下UNUserNotifications的requestAuthorization为何不显示授权弹窗?

解决Mac Catalyst(macOS 10.15-10.15.3)下通知授权弹窗不显示的问题

我之前适配Mac Catalyst时也碰到过一模一样的问题——iOS和iPadOS上调用UNUserNotificationCenter.current().requestAuthorization()能正常弹出授权弹窗,但在macOS 10.15到10.15.3版本(对应Xcode 11至11.3.1)里完全没反应,手动开启通知后功能倒是正常运行。这是Mac Catalyst早期版本的已知系统级bug,苹果在后续的系统和Xcode更新里修复了这个问题,下面是几个经过验证的解决办法:

1. 确保Info.plist配置正确

首先要确认你的Info.plist里已经添加了macOS所需的通知权限描述字段:

  • 添加NSUserNotificationUsageDescription键,填写清晰的权限用途说明(比如"我们会推送重要的更新和提醒给您")。
    早期Mac Catalyst版本只会读取这个macOS专属字段,而非iOS的NSNotificationSettingsUsageDescription,如果没配置这个,系统可能会静默拒绝授权请求。

2. 手动引导用户开启权限(核心解决方案)

由于系统自带的授权弹窗无法触发,我们可以先检查当前授权状态,针对未决定的用户,用自定义弹窗引导他们去系统设置手动开启:

UNUserNotificationCenter.current().getNotificationSettings { settings in
    DispatchQueue.main.async {
        switch settings.authorizationStatus {
        case .notDetermined:
            // 显示自定义引导弹窗
            let alert = UIAlertController(
                title: "需要通知权限",
                message: "为了给您推送重要消息,请前往系统设置 > [您的应用名称] > 通知 开启权限",
                preferredStyle: .alert
            )
            alert.addAction(UIAlertAction(title: "立即前往", style: .default) { _ in
                guard let settingsURL = URL(string: UIApplication.openSettingsURLString) else { return }
                UIApplication.shared.open(settingsURL)
            })
            alert.addAction(UIAlertAction(title: "稍后再说", style: .cancel))
            // 确保当前有可present的ViewController
            if let topVC = UIApplication.shared.windows.first?.rootViewController {
                topVC.present(alert, animated: true)
            }
        case .denied:
            // 用户已拒绝权限,同样引导去设置修改
            let alert = UIAlertController(
                title: "通知权限已关闭",
                message: "您可以前往系统设置开启通知权限,接收我们的推送消息",
                preferredStyle: .alert
            )
            alert.addAction(UIAlertAction(title: "去设置", style: .default) { _ in
                guard let settingsURL = URL(string: UIApplication.openSettingsURLString) else { return }
                UIApplication.shared.open(settingsURL)
            })
            alert.addAction(UIAlertAction(title: "取消", style: .cancel))
            if let topVC = UIApplication.shared.windows.first?.rootViewController {
                topVC.present(alert, animated: true)
            }
        default:
            // 权限已授权,正常处理通知逻辑
            break
        }
    }
}

3. 升级系统或Xcode(彻底解决)

如果项目允许的话,建议引导用户升级到macOS 10.15.4及以上版本,或者你自己升级Xcode到11.4及以上进行编译——苹果在这些版本里修复了Mac Catalyst的通知授权弹窗触发问题,升级后就能像iOS一样正常弹出系统授权弹窗了。

需要注意的是,不管用哪种方法,当用户手动开启通知权限后,推送功能就能正常运行,这和你描述的情况一致,核心就是绕过早期Mac Catalyst的这个bug。

内容的提问来源于stack exchange,提问作者Slava Gorloff

火山引擎 最新活动