3

我目前正在通过 dispatch_async 调用 storeViewController loadProductWithParameters 。是否可以设置超时值,使其仅尝试获取 X 秒的结果然后放弃?

4

2 回答 2

1

我通过使用下面的类方法而不是直接调用 loadProductWithParameters 来实现自己的超时。由于 adispatch_after__block变量,它超时。

+ (void)loadProductViewControllerWithTimeout:(NSTimeInterval)timeout
                      storeKitViewController:(SKStoreProductViewController *)storeKitViewController
                                  parameters:(NSDictionary *)parameters
                           completionHandler:(void (^)(BOOL result, NSError *error))completionHandler {

  __block BOOL hasReturnedOrTimedOut = NO;

  [storeKitViewController loadProductWithParameters:parameters completionBlock:^(BOOL result, NSError *error) {
    dispatch_async(dispatch_get_main_queue(), ^{
      if (!hasReturnedOrTimedOut) {
        hasReturnedOrTimedOut = YES;
        if (completionHandler) completionHandler(result, error);
      }
    });
  }];

  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeout * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    if (!hasReturnedOrTimedOut) {
      hasReturnedOrTimedOut = YES;
      if (completionHandler) completionHandler(NO, nil); // Or add your own error instead of |nil|.
    }
  });
}

我最新的应用更新被 Apple 拒绝了,因为 loadProductWithParameters 从未调用它的 completionBlock 并阻止我的用户在 iTunes 上购买歌曲......希望这会有所帮助。

于 2014-10-29T17:28:40.683 回答
0

我已经完成了它:

  __block BOOL timeoutOrFinish = NO;

  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(30 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    if(!timeoutOrFinish) {
      timeoutOrFinish = YES;
      [self dismissAndShowError];
    }
  });

  [storeViewController loadProductWithParameters:parameters completionBlock:^(BOOL result, NSError * _Nullable error) {
    if(timeoutOrFinish) {
      return;
    }

    timeoutOrFinish = YES;
    //[[NetworkManager sharedManager] showNetworkActivityIndicator:NO];
    if(error) {
      [self dismissAndShowError];
    }
  }];

  [self.view.window.rootViewController presentViewController:storeViewController animated:YES completion:nil];

wheredismissAndShowError方法运行dismissViewControllerAnimated并显示错误警报。

基本上,您有一个单独的计时器(在我的情况下为 30 秒)来切换标志。在那之后,如果商店仍未加载,我将其关闭并显示错误。否则,将调用完成(在取消、完成和错误时)并根据状态处理所有操作。

于 2017-08-02T22:08:24.813 回答