开发者社区 问答 正文

移动推送 iOS SDK: Main Thread Checker: UI API called on a background thread


Xcode 升级到 Xcode 9后,集成时若提示下述错误:

  1. [backcolor=transparent]Main[backcolor=transparent] [backcolor=transparent]Thread[backcolor=transparent] [backcolor=transparent]Checker[backcolor=transparent]:[backcolor=transparent] UI API called on a background thread

请检查工程中,是否在后台线程(非主线程)调用 AppKit、UIKit相关的API,比如iOS 10+ 请求通知权限时,[application registerForRemoteNotifications];在回调非主线程中执行,则Xcode 9会报上述错误。
  1. [backcolor=transparent][[backcolor=transparent]_notificationCenter requestAuthorizationWithOptions[backcolor=transparent]:[backcolor=transparent]UNAuthorizationOptionAlert[backcolor=transparent] [backcolor=transparent]|[backcolor=transparent] [backcolor=transparent]UNAuthorizationOptionBadge[backcolor=transparent] [backcolor=transparent]|[backcolor=transparent] [backcolor=transparent]UNAuthorizationOptionSound[backcolor=transparent] completionHandler[backcolor=transparent]:^([backcolor=transparent]BOOL granted[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]NSError[backcolor=transparent] [backcolor=transparent]*[backcolor=transparent] [backcolor=transparent]_Nullable[backcolor=transparent] error[backcolor=transparent])[backcolor=transparent] [backcolor=transparent]{
  2. [backcolor=transparent]    [backcolor=transparent]if[backcolor=transparent] [backcolor=transparent]([backcolor=transparent]granted[backcolor=transparent])[backcolor=transparent] [backcolor=transparent]{
  3. [backcolor=transparent]        [backcolor=transparent]// granted
  4. [backcolor=transparent]        [backcolor=transparent]NSLog[backcolor=transparent](@[backcolor=transparent]"User authored notification."[backcolor=transparent]);
  5. [backcolor=transparent]        [backcolor=transparent]// 向APNs注册,获取deviceToken
  6. [backcolor=transparent]        [backcolor=transparent][[backcolor=transparent]application registerForRemoteNotifications[backcolor=transparent]];
  7. [backcolor=transparent]    [backcolor=transparent]}[backcolor=transparent] [backcolor=transparent]else[backcolor=transparent] [backcolor=transparent]{
  8. [backcolor=transparent]        [backcolor=transparent]// not granted
  9. [backcolor=transparent]        [backcolor=transparent]NSLog[backcolor=transparent](@[backcolor=transparent]"User denied notification."[backcolor=transparent]);
  10. [backcolor=transparent]    [backcolor=transparent]}
  11. [backcolor=transparent]}];

应修改为:
  1. [backcolor=transparent][[backcolor=transparent]_notificationCenter requestAuthorizationWithOptions[backcolor=transparent]:[backcolor=transparent]UNAuthorizationOptionAlert[backcolor=transparent] [backcolor=transparent]|[backcolor=transparent] [backcolor=transparent]UNAuthorizationOptionBadge[backcolor=transparent] [backcolor=transparent]|[backcolor=transparent] [backcolor=transparent]UNAuthorizationOptionSound[backcolor=transparent] completionHandler[backcolor=transparent]:^([backcolor=transparent]BOOL granted[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]NSError[backcolor=transparent] [backcolor=transparent]*[backcolor=transparent] [backcolor=transparent]_Nullable[backcolor=transparent] error[backcolor=transparent])[backcolor=transparent] [backcolor=transparent]{
  2. [backcolor=transparent]    [backcolor=transparent]if[backcolor=transparent] [backcolor=transparent]([backcolor=transparent]granted[backcolor=transparent])[backcolor=transparent] [backcolor=transparent]{
  3. [backcolor=transparent]        [backcolor=transparent]// granted
  4. [backcolor=transparent]        [backcolor=transparent]NSLog[backcolor=transparent](@[backcolor=transparent]"User authored notification."[backcolor=transparent]);
  5. [backcolor=transparent]        [backcolor=transparent]// 向APNs注册,获取deviceToken
  6. [backcolor=transparent]        dispatch_async[backcolor=transparent]([backcolor=transparent]dispatch_get_main_queue[backcolor=transparent](),[backcolor=transparent] [backcolor=transparent]^{
  7. [backcolor=transparent]            [backcolor=transparent][[backcolor=transparent]application registerForRemoteNotifications[backcolor=transparent]];
  8. [backcolor=transparent]        [backcolor=transparent]};
  9. [backcolor=transparent]    [backcolor=transparent]}[backcolor=transparent] [backcolor=transparent]else[backcolor=transparent] [backcolor=transparent]{
  10. [backcolor=transparent]        [backcolor=transparent]// not granted
  11. [backcolor=transparent]        [backcolor=transparent]NSLog[backcolor=transparent](@[backcolor=transparent]"User denied notification."[backcolor=transparent]);
  12. [backcolor=transparent]    [backcolor=transparent]}
  13. [backcolor=transparent]}];

展开
收起
猫饭先生 2017-10-24 10:09:49 1797 分享 版权
阿里云 AI 助理回答

您遇到的问题是由于在非主线程(后台线程)调用了UI相关的API,这在Xcode 9及之后的版本中会触发警告或错误。根据您的描述和代码示例,问题在于registerForRemoteNotifications方法被直接在回调中执行,而这个回调可能不在主线程上运行。

您已经正确地展示了如何修正这个问题:通过使用dispatch_async函数将注册远程通知的操作切换到主线程执行。这样做可以确保所有与UI相关的操作都在主线程上进行,避免了Xcode的警告或错误提示。下面是修正后的代码段:

_notificationCenter requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {
    if (granted) {
        NSLog(@"User authorized notification.");
        // 确保在主线程上执行注册操作
        dispatch_async(dispatch_get_main_queue(), ^{
            [[UIApplication sharedApplication] registerForRemoteNotifications];
        });
    } else {
        NSLog(@"User denied notification.");
    }
}];

这段代码中,dispatch_get_main_queue()获取到了主线程的队列,然后通过dispatch_async异步地在这个队列上执行了注册远程通知的操作,从而符合了iOS开发的最佳实践,即只在主线程上处理UI更新和UI相关的API调用。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答