swift 只能从主线程调用UI应用程序.registerForRemoteNotifications()

wlwcrazw  于 2023-01-19  发布在  Swift
关注(0)|答案(8)|浏览(183)

Xcode 9(iOS 11)在注册推送(远程)通知时向我显示错误/警告。
以下是错误消息

这是我试过的代码

let center  = UNUserNotificationCenter.current()
center.delegate = self
center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in
        if error == nil{
              UIApplication.shared.registerForRemoteNotifications()
        }
 }

错误/警告行:

UI应用程序.共享.远程通知注册表()
如何解决这一问题?

mitkmikd

mitkmikd1#

快速4

您可以使用以下方法解决此问题

DispatchQueue.main.async {
  UIApplication.shared.registerForRemoteNotifications()
}

希望这能帮上忙...

2q5ifsrm

2q5ifsrm2#

对于Objective C,以下代码有效

dispatch_async(dispatch_get_main_queue(), ^{
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    });
hpcdzsge

hpcdzsge3#

TL;DR:

所有UI操作都应该在主线程中完成以避免问题。如果没有这样做,主线程检测器(Xcode 9中新引入的调试功能)将在运行时产生问题。因此,将代码 Package 在主线程块中,如下所示,以避免故障和运行时警告。

DispatchQueue.main.async {
    UIApplication.shared.registerForRemoteNotifications()
}

在Xcode版本9之前的版本中,与主线程相关的警告会以文本形式打印在控制台区域。无论如何,您可以选择在Edit SchemeDiagnostic设置中禁用(不推荐使用)主线程检测器。

说明:

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

如果你有任何旧的SDK或框架,当更新到Xcode 9时,你可能会面临这个警告,因为一些UIKit方法调用没有被 Package 在主线程中。更新到最新版本将修复这个问题(如果开发者意识到并修复了它)。

引用自Xcode 9测试版发行说明:
*Xcode 9中的新增功能-主线程检测器。
*从后台线程启用UI API误用检测

  • 检测不在主线程上进行的AppKit、UIKit和WebKit方法调用。
  • 调试时自动启用,可在方案编辑器的“诊断”选项卡中禁用。
  • “主线程检测器”支持Swift和C语言。
km0tfn4u

km0tfn4u4#

错误消息非常清楚:将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
        }
}
hgqdbh6s

hgqdbh6s5#

在雨燕4或5

DispatchQueue.main.async {
  UIApplication.shared.registerForRemoteNotifications()
}

关于目标C

dispatch_async(dispatch_get_main_queue(), ^{
        [[UIApplication sharedApplication] registerForRemoteNotifications];
});
vlurs2pr

vlurs2pr6#

这也是在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()
                }
            }
        })
emeijp43

emeijp437#

希望这能有所帮助

DispatchQueue.main.async(execute: {
  UIApplication.shared.registerForRemoteNotifications()
})
yrefmtwq

yrefmtwq8#

这对我很有效。感谢@Mason11987在上面的评论。

DispatchQueue.main.async() { code }

相关问题