必须仅从主线程调用UIApplication.registerForRemoteNotifications()

Kru*_*nal 71 push-notification ios swift unusernotificationcenter swift4

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()
        }
 }
Run Code Online (Sandbox Code Playgroud)

错误/警告线:

UIApplication.shared.registerForRemoteNotifications()

怎么解决这个?

Was*_*mon 130

swift4中

你可以解决这个问题

DispatchQueue.main.async(execute: {
  UIApplication.shared.registerForRemoteNotifications()
}) 
Run Code Online (Sandbox Code Playgroud)

希望这会有所帮助......

  • 我喜欢`DispatchQueue.main.async(){code}` (11认同)
  • @PoojaSrivastava`dispatch_async(dispatch_get_main_queue(),^ {// Do stuff});` (4认同)
  • 对不起,错字:`DispatchQueue.main.async(执行:UIApplication.shared.registerForRemoteNotifications)`.`execute`需要一个函数/闭包类型`() - > Void`所以`registerForRemoteNotifications`有效 (3认同)

R. *_*han 38

对于Objective C,以下代码有效

    dispatch_async(dispatch_get_main_queue(), ^{
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    });
Run Code Online (Sandbox Code Playgroud)


bad*_*esh 34

TL; DR:
所有UI操作都应该在主线程中完成,以避免出现问题.如果没有这样做,主线程检查器(XCode 9中新引入的调试功能)将在运行时产生问题.因此,将代码包装在主线程块中,如下所示,以避免毛刺和运行时警告.

DispatchQueue.main.async {
    UIApplication.shared.registerForRemoteNotifications()
}
Run Code Online (Sandbox Code Playgroud)

在版本之前的Xcode版本中.9,与主线程相关的警告将以文本方式打印在控制台区域中.无论如何,您可以选择在编辑方案诊断设置中禁用(不推荐的方法)主线程检查器.


说明:

Apple在XCode 9中引入了一个新的调试选项,用于检查运行时UIKit和操纵UI元素的其他API的问题.如果在运行时对UIKit API的UI元素进行了任何更改,没有主线程块,则极有可能导致UI故障和崩溃.在主线程检查器默认情况下启用捕捉这些问题在运行时.您可以在编辑方案窗口中禁用主线程检查器,如下所示,但实际上并不建议这样做:

禁用主线程检查器

如果您有任何较旧的SDK或Frameworks,则在更新到Xcode 9时,您可能会遇到此警告,因为某些UIKit方法调用不会包含在主线程中.将它们更新到最新版本将解决问题(如果开发人员知道并修复它).

引自XCode 9测试版发行说明:

  • Xcode 9中的新功能 - 主线程检查器.
    • 允许从后台线程检测UI API滥用
    • 检测未在主线程上进行的AppKit,UIKit和WebKit方法调用.
    • 在调试期间自动启用,可以在方案编辑器的"诊断"选项卡中禁用.
    • 主线程检查器适用于Swift和C语言.

  • @Honey发行说明通常包含所有必要的更改:) (3认同)
  • @Honey有些人阅读发行说明和文档;-) (3认同)
  • 很好奇你是怎么这么快就学会了这个 Xcode 9 新设置的?还没有 WWDC 视频! (2认同)
  • @BadhanGanesh(我没有downvote也没有upvoted)如果这不是你想要的那么重写它...因为它就像有人说我有问题X ...然后你回复你*可以*做Y .... OP正在寻找答案.如果这只是一个解释而不是明确表示它不是答案 (2认同)

vad*_*ian 6

错误消息非常清楚:调度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
        }
}
Run Code Online (Sandbox Code Playgroud)


小智 6

在 Swift 4 或 5 中

DispatchQueue.main.async {
  UIApplication.shared.registerForRemoteNotifications()
}
Run Code Online (Sandbox Code Playgroud)

关于Objectiv-C

dispatch_async(dispatch_get_main_queue(), ^{
        [[UIApplication sharedApplication] registerForRemoteNotifications];
});
Run Code Online (Sandbox Code Playgroud)