ios – NSURLSessionTask在使用后台配置时,不会在超时后调用

我正在使用带有后台会话的NSURLSessionDownloadTask来实现我所有的REST请求.这样我可以使用相同的代码,而不必考虑我的应用程序在后台或前台.

我的后端已经死了一段时间,我已经借此机会来测试NSURLSession如何超时.

令我惊讶的是,我的NSURLSessionTaskDelegate回调没有被调用.无论我在NSURLRequest或NSURLSessionConfiguration上设置了什么超时,我从来没有收到任何来自iOS的回调,告诉我该请求的确超时.

也就是说,当我在后台会话上启动NSURLSessionDownloadTask时.相同的行为发生在应用程序在后台或前台.

示例代码:

- (void)launchDownloadTaskOnBackgroundSession {
    NSString *sessionIdentifier = @"com.mydomain.myapp.mySessionIdentifier";
    NSURLSessionConfiguration *backgroundSessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfiguration:sessionIdentifier];
    backgroundSessionConfiguration.requestCachePolicy = NSURLRequestReloadIgnoringCacheData;
    backgroundSessionConfiguration.timeoutIntervalForRequest = 40;
    backgroundSessionConfiguration.timeoutIntervalForResource = 65;
    NSURLSession *backgroundSession = [NSURLSession sessionWithConfiguration:backgroundSessionConfiguration delegate:self delegateQueue:[NSOperationQueue mainQueue]];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.timeout.com/"]];
    request.timeoutInterval = 30;
    NSURLSessionDownloadTask *task = [backgroundSession downloadTaskWithRequest:request];
    [task resume];
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    NSLog(@"URLSession:task:didCompleteWithError: id=%d,error=%@",task.taskIdentifier,error);
}

但是,当我使用默认会话时,我在30秒之后收到一个错误回调(我在请求级设置的超时).

示例代码:

- (void)launchDownloadTaskOnDefaultSession {
    NSURLSessionConfiguration *defaultSessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
    defaultSessionConfiguration.requestCachePolicy = NSURLRequestReloadIgnoringCacheData;
    defaultSessionConfiguration.timeoutIntervalForRequest = 40;
    defaultSessionConfiguration.timeoutIntervalForResource = 65;
    NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:defaultSessionConfiguration delegate:self delegateQueue:[NSOperationQueue mainQueue]];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.timeout.com/"]];
    request.timeoutInterval = 30;
    NSURLSessionDownloadTask *task = [defaultSession downloadTaskWithRequest:request];
    [task resume];
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    NSLog(@"URLSession:task:didCompleteWithError: id=%d,error);
}

在文档中似乎找不到任何表明在使用后台会话时超时应该有所不同的事情.

有没有人碰到这个问题呢?
这是一个bug还是一个功能?

我正在考虑创建一个错误报告,但是我通常在SO(几分钟)内得到的反馈比bug记者(六个月)更快.

问候,

解决方法

自iOS8以来,如果服务器没有响应,NSUrlSession在后台模式下不会调用此委托方法.
– (void)URLSession:(NSURLSession *)会话任务:(NSURLSessionTask *)任务didCompleteWithError:(NSError *)错误
下载/上传将无限期地保持空闲.
该代理在iOS7上调用,服务器未响应时出现错误.

In general,an NSURLSession background session does not fail a task if
something goes wrong on the wire. Rather,it continues looking for a
good time to run the request and retries at that time. This continues
until the resource timeout expires (that is,the value of the
timeoutIntervalForResource property in the NSURLSessionConfiguration
object you use to create the session). The current default for that
value is one week!

Quoted information taken from this Source

换句话说,在iOS7中失败超时的行为是不正确的.在后台会话的上下文中,由于网络问题,不会立即失败更有趣.因此,自从iOS8以来,即使遇到超时和网络丢失,NSURLSession任务也会继续.它仍然继续,直到达到timeoutIntervalForResource.

所以基本上timeoutIntervalForRequest将不会在后台会话中工作,但是timeoutIntervalForResource会.

以上是来客网为你收集整理的ios – NSURLSessionTask在使用后台配置时,不会在超时后调用全部内容,希望文章能够帮你解决ios – NSURLSessionTask在使用后台配置时,不会在超时后调用所遇到的程序开发问题。

如果觉得来客网网站内容还不错,欢迎将来客网网站推荐给程序员好友。