【问题标题】:iOS NSURLSession, how to retry in didCompleteWithErroriOS NSURLSession,如何在 didCompleteWithError 中重试
【发布时间】:2015-07-03 14:40:01
【问题描述】:

我想在我的服务器上尝试一个 post call 直到它成功,我想每 30 秒尝试一次。

所以我使用 NSURLSession 进行通话:

 NSURLSessionDownloadTask *task = [self.session downloadTaskWithRequest:request];
task.taskDescription = [NSString stringWithFormat:@"Downloading file %@", [path lastPathComponent]];
[task resume];

然后如果发生错误(例如没有网络)我有一个错误:

-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error

我的问题是如何在 30 秒内执行相同的呼叫,我的应用会在后台运行吗?

我尝试了调度、NSThread 和 performSelector,但看起来它在后台不起作用:(

谢谢。

【问题讨论】:

    标签: ios post background nsurlsession


    【解决方案1】:

    一些观察:

    1. 如果您想在应用程序不再处于前台的情况下在几秒钟后重试,您可能只想要求操作系统多一点时间来执行有限长度的任务。见Extending Your App's Background Execution Time。如果您这样做,您的标准计时器 dispatch_after 或其他任何东西都应该可以正常工作。

      请注意,您只有 30 秒(低于以前的 iOS 版本中的 3 分钟)来完成此后台任务。话虽如此,我个人怀疑如果用户没有连接,那么他们很有可能在接下来的 30 秒内也没有连接,所以我不确定这个重试逻辑是否有任何好处如果应用没有运行。

    2. 顺便说一句,与其在 30 秒内重试,不如考虑使用Reachability,以便在网络可用时收到通知。在网络重新建立之前,再试是没有意义的。

    3. 另一种方法是使用backgroundSessionConfigurationWithIdentifierNSURLSessionConfiguration。见Downloading Content in the Background。如果您这样做,您有超过 3 分钟的时间来完成请求。一旦重新建立连接,它将自动启动。这种技术的缺点是(a)后台会话不如前台会话响应速度快; (b) 仅限于 iOS 7 及更高版本;并且 (c) 您必须实现基于委托的 NSURLSession 再现,而不是完成块再现,这需要更多的工作。

    坦率地说,我通常倾向于采用第三种方法,但每种方法都有其优点。

    【讨论】:

    • 如何实现第三种方法?你能提供一个重试下载任务的例子吗?
    • 第三种方法的美妙之处在于您不必执行任何重试逻辑。重新建立网络连接后,系统会自动尝试执行请求。
    • 那么,如果didCompleteWithError 被调用时出现非零错误,这是否(可能)意味着在它因错误而失败之前进行了多次重试?
    • 你得到的背景是NSURLSession(即一个NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier)?
    • 我还没有收到非零错误。那是一个理论问题。但是,是的,我使用的是backgroundSessionConfigurationWithIdentifier
    猜你喜欢
    • 2015-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-02
    • 1970-01-01
    相关资源
    最近更新 更多