Swift 4 – UIApplication.registerForRemoteNotifications()只能从主线程调用
Xcode 9(iOS 11)在注册Push(远程)通知时显示错误/警告。
这是错误信息
这里是代码,我试过了:
let center = UNUserNotificationCenter.current() center.delegate = self center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in if error == nil{ UIApplication.shared.registerForRemoteNotifications() } }
错误/警告线:
UIApplication.shared.registerForRemoteNotifications()
如何解决这个问题?
在swift4
你可以用这个来解决这个问题
DispatchQueue.main.async(execute: { UIApplication.shared.registerForRemoteNotifications() })
希望这将有助于…
TL; DR:
所有UI操作应该在主线程中完成以避免问题。 如果没有这样做, 主线程检查器 (在XCode 9中新引入的debuggingfunction)将在运行时产生问题。 您可以select(不是推荐的方法)在编辑scheme的诊断设置中禁用主线程检查器
Apple在XCode 9中引入了一个新的debugging选项,用于在运行时检查UIKit和其他操作UI元素的API的问题。 如果在运行系统中UIKit API的UI元素没有主线程块,那么很可能会导致UI故障和崩溃。 主线程检查器默认情况下启用,以在运行时捕获这些问题。 您可以在编辑计划窗口中禁用主线程检查程序 ,就像下面一样,尽pipe并不真的build议这样做:
从XCode 9testing版发布说明引用:
- Xcode 9中的新增function – 主线程检查器。
- 从后台线程启用对UI API滥用的检测
- 检测未在主线程上进行的AppKit,UIKit和WebKit方法调用。
- 在debugging期间自动启用,并且可以在scheme编辑器的“诊断”选项卡中禁用。
- 主线程检查器使用Swift和C语言。
对于Objective C,下面的代码起作用
dispatch_async(dispatch_get_main_queue(), ^{ [[UIApplication sharedApplication] registerForRemoteNotifications]; });
错误消息非常清晰:向主线程发送registerForRemoteNotifications
。
我将使用granted
参数,并相应地处理error
center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in if granted { DispatchQueue.main.async { UIApplication.shared.registerForRemoteNotifications() } } else { print(error!) // handle the error } }
这在Swift 4.0中也是正确的
UNUserNotificationCenter.current().delegate = self UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.sound,.badge], completionHandler: {(granted,error) in if granted{ DispatchQueue.main.async { application.registerForRemoteNotifications() } } })