iOS NSURLSession,如何在didCompleteWithError中重试

我想在我的服务器上尝试一个post,直到它成功,我想每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秒内执行相同的调用?

我尝试使用dispatch,NSThread和performSelector,但看起来它在后台不起作用:(

谢谢。

一些观察:

  1. 如果您想在30秒内再次尝试,即使应用程序不再位于前台,您可能只想让操作系统多花一点时间来执行有限长度的任务。 请参阅执行有限长度任务 。 如果你这样做,你的标准计时器, dispatch_after或其他什么,应该可以正常工作。

    请注意,您只需3分钟即可完成此后台任务。 我知道你说你会倾向于在30秒内再试一次,但我个人怀疑如果用户没有连接,他们很可能在接下来的几分钟内没有连接。

  2. 顺便说一句,如果在应用程序仍在运行时重试,我可能会建议不要在30秒内再次尝试。 在我看来,更好的是使用Reachability,以便在网络可用时通知您。 在网络重新建立之前再次尝试是没有意义的。

  3. 另一种方法是使用NSURLSessionConfiguration 。 请参阅后台下载内容 。 如果您这样做,您有超过3分钟的时间来完成请求。 一旦重新建立连接,它将自动启动。 这种技术的缺点是(a)后台会话不像前台会话那样响应; (b)仅限于iOS 7及更高版本; (c)你必须实现NSURLSession的基于代表的再现,而不是完成块再现,这是一个更多的工作。

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