首页 > 解决方案 > react-native iOS原生模块:异步激活网络指示器的调用方法

问题描述

我正在编写一个本机模块,该模块从我无权访问的封闭源代码框架二进制文件中调用函数。它会阻止网络调用并激活网络指示器。我希望能够在后台异步运行它,它有点开箱即用,但是当我这样做时,我得到这个警告/错误并且调用有点停顿:

Main Thread Checker: UI API called on a background thread: -[UIApplication setNetworkActivityIndicatorVisible:]

如果我在我的 RN 模块中使用以下代码将它放在主队列中,调用会阻塞所有内容,直到它们完成。

- (dispatch_queue_t)methodQueue
{
  return dispatch_get_main_queue();
}

下面是一个暴露给 JS 的方法的例子:

RCT_REMAP_METHOD(createSession,
                 userIDtoken:(NSString *)userIDtoken
                 createSessionWithResolver:(RCTPromiseResolveBlock)resolve
                 rejecter:(RCTPromiseRejectBlock)reject)
{
    Boolean connected = [_networkController startSession:userIDtoken isTest:true];
    NSString *success = @"session created";
    if (connected){
      resolve(success);
    } else {
      NSError *error = [NSError errorWithDomain:@"ConnectionError" code:1 userInfo:nil];
      reject(@"session_creation_failed", @"Cannot create sessions", error);
    }
}

_networkController startSession应该在后台运行而不会抛出警告/错误并且不会阻塞主线程。有没有办法做到这一点?

标签: iosobjective-creact-native

解决方案


您不能UIKit在后台线程上进行 API 调用,因为它不是线程安全的。

您可以删除 RN 模块methodQueue设置,以便您的模块方法将在后台线程上再次调用,并且不会阻塞主线程。每当您需要调用[UIApplication setNetworkActivityIndicatorVisible:](或任何其他需要主队列的方法)时,都可以将其分派到主线程,例如:

dispatch_async(dispatch_get_main_queue(), ^{
    [UIApplication.sharedApplication setNetworkActivityIndicatorVisible:YES];
});

如果您只需要在设置活动指示器后解决承诺,您还可以在更改活动指示器可见性后将您的调用以解决/拒绝放在同一块内。


推荐阅读