请求通知权限未授予时弹窗引发App崩溃的解决方法
解决后台线程操作UI导致的弹窗异常问题
这个报错的核心原因很明确:UNUserNotificationCenter的权限请求回调是在后台线程执行的,而所有UI相关操作(比如present弹窗、修改视图布局)必须在主线程完成,否则就会触发这类布局引擎的异常。
你只需要将弹窗展示的代码包裹在DispatchQueue.main.async里,确保UI操作在主线程执行即可,修改后的完整代码如下:
let center = UNUserNotificationCenter.current() center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in // 先处理错误,逻辑更清晰 if let error = error { print(error) return } if !granted { // 把所有UI操作切换到主线程执行 DispatchQueue.main.async { let permissionNotGrantedAlert = UIAlertController( title: "Notifications not enabled", message: "We won't be able to send you notifications.\n\nYou can allow us to send you notifications from your device's settings.", preferredStyle: .alert ) permissionNotGrantedAlert.addAction(UIAlertAction( title: "Go to settings", style: .default, handler: { action in // 用可选绑定替代强制解包,避免潜在崩溃 if let settingsURL = URL(string: UIApplicationOpenSettingsURLString) { UIApplication.shared.open(settingsURL) } } )) // 空handler可以省略,简化代码 permissionNotGrantedAlert.addAction(UIAlertAction(title: "OK", style: .default)) self.present(permissionNotGrantedAlert, animated: true) } } }
额外补充几个优化点:
- 调整了错误处理的顺序,先处理异常再判断权限状态,逻辑更顺畅;
- 对打开设置的URL做了可选绑定,避免原代码中
!强制解包可能导致的崩溃(虽然这个URL几乎不会无效,但养成安全的编码习惯更稳妥); - 去掉了
OK按钮的空handler,UIAlertAction允许省略该参数,让代码更简洁。
记住一个iOS开发的核心规则:所有涉及UIKit的操作(创建控件、修改布局、弹窗展示等),必须在主线程执行,否则很容易出现各种难以排查的布局异常或崩溃。
内容的提问来源于stack exchange,提问作者user13583757
相关产品推荐
相关产品推荐

