我目前正在通过dispatch_async调用storeViewController loadProductWithParameters。是否可以设置超时值,以便它只尝试获取X秒的结果,然后放弃?
答案 0 :(得分:1)
我通过使用下面的类方法而不是直接调用loadProductWithParameters来实现我自己的超时。由于dispatch_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上的歌曲...希望这会有所帮助。
答案 1 :(得分: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];
其中dismissAndShowError
方法运行dismissViewControllerAnimated
并显示错误警告。
基本上,你有一个单独的计时器(在我的情况下是30秒)来切换标志。在此之后,如果仍未加载商店,我将其关闭并显示错误。否则,调用完成(取消,完成和错误)并根据状态处理所有操作。