ios UIApplication.registerForRemoteNotifications() 只能从主线程调用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44391367/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 09:12:15  来源:igfitidea点击:

UIApplication.registerForRemoteNotifications() must be called from main thread only

iosswiftpush-notificationswift4unusernotificationcenter

提问by Krunal

Xcode 9 (iOS 11) showing me an error/warning while registering for Push (remote) notification.

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

Here is error message

这是错误信息

enter image description here

在此处输入图片说明

And here is code, I've tried:

这是代码,我试过:

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

Error/Warning Line:

错误/警告行:

UIApplication.shared.registerForRemoteNotifications()

UIApplication.shared.registerForRemoteNotifications()

How to resolve this?

如何解决这个问题?

回答by Wasim K. Memon

In swift4

swift4

You can solve this issue with

你可以解决这个问题

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

Hope this will help...

希望这会有所帮助...

回答by R. Mohan

For Objective C, the below code works

对于目标 C,以下代码有效

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

回答by badhanganesh

TL;DR:
All UI manipulations should be done in the Main Thread to avoid problems. If failed to do so, Main Thread Checker(Newly introduced debugging feature in XCode 9) will produce issues at Runtime. So wrap your code in Main Thread block like below to avoid glitches and runtime warnings.

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

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

In Xcode releases before ver. 9, the warnings related to main thread would get printed in the console area textually. Anyway, you can optionally disable (not a recommended approach) the Main Thread Checker in the Diagnosticsettings in Edit Scheme.

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


Explanation:


解释:

Apple introduced a new debugging option in XCode 9 for checking issues at Runtime for UIKit and other API's that manipulate UI elements. If there's any change to the UI elements from UIKit API at Runtime, without a Main thread block, it is highly likely to cause UI glitches and crashes. The Main Thread Checkeris enabled by default to catch those issues at runtime. You can disable Main Thread Checkerin the Edit Schemewindow just like below, although it is not really recommended to do so:

Disable Main Thread Checker

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

禁用主线程检查器

If you have any older SDK's or Frameworks, when updating to Xcode 9, you may face this warning since some of the UIKit method calls wouldn't have been wrapped in Main Thread. Updating them to latest version would fix the issue (if the developer is aware of it and fixed it).

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

Quote from XCode 9 beta release notes:

引自 XCode 9 beta 发行说明:

  • New in Xcode 9 – Main Thread Checker.
    • Enable detection of UI API misuse from background thread
    • Detects AppKit, UIKit, and WebKit method calls that are not made on the main thread.
    • Automatically enabled during debugging, and can be disabled in the Diagnostic tab of the scheme editor.
    • Main Thread Checker works with Swift and C languages.
  • Xcode 9 中的新功能——主线程检查器。
    • 启用从后台线程检测 UI API 滥用
    • 检测不是在主线程上进行的 AppKit、UIKit 和 WebKit 方法调用。
    • 在调试期间自动启用,并且可以在方案编辑器的诊断选项卡中禁用。
    • 主线程检查器适用于 Swift 和 C 语言。

回答by vadian

The error message is pretty clear: dispatch registerForRemoteNotificationsto the main thread.

错误信息很清楚:调度registerForRemoteNotifications到主线程。

I would use the grantedparameter and handle the erroraccordingly

我会使用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
        }
}

回答by Sunil Targe

This is also correct way to do in Swift 4.0

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

回答by Basir Alam

Hope this will help

希望这会有所帮助

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

回答by Gibraltar

This is what worked for me. Courtesy of @Mason11987 in the accepted comment above.

这对我有用。感谢@Mason11987 在上面接受的评论中。

DispatchQueue.main.async() { code }