【发布时间】:2014-06-10 21:53:06
【问题描述】:
我正在使用 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=%@", task.taskIdentifier, error);
}
我似乎在文档中找不到任何暗示使用后台会话时超时应该表现不同的东西。
有没有人也遇到过这个问题? 这是错误还是功能?
我正在考虑创建错误报告,但我通常会比错误报告者(六个月)更快地获得关于 SO(几分钟)的反馈。
问候,
【问题讨论】:
-
你有没有找到解决这个问题的方法?
-
是和不是。否:我向 Apple 报告了这个错误,Apple 很友好地回答我的错误报告不够完整。我懒得提供超时的测试。很难做到。
-
是的:我的问题是使用后台会话时 GUI 将等待回调。在这种情况下,如果它不回叫,那会很烦人,因为您无法更新您的 UI。所以我所做的就是在处理从 UI 发起的网络调用并需要反馈时不使用后台会话。
-
长话短说:我使用后台会话仅在后台执行同步,在处理具有 GUI 反馈的网络调用时使用良好的旧 AFNetworking。我会回答你的问题吗?
-
我提交了一个错误,因为使用httpbin.org/delay/10 并将请求 timeoutInterval 设置为 5 很容易重现。使用 NSURLConnection 的请求在 5 秒后按预期超时,但 NSURLSession 完成请求需要 10 秒。
标签: ios ios7.1 nsurlsession nsurlsessiondownloadtask nsurlsessionconfiguration