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




