Nic*_*son 7 timeout background objective-c nsurlsession nsurlsessionconfiguration
我遇到了一个问题,那就是后端速度慢,后台配置下载数据.
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration backgroundSessionConfiguration:identifier];
_backgroundSession = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];
NSURLSessionDownloadTask *downloadTask = [_backgroundSession downloadTaskWithURL:URL];
[downloadTask resume];
Run Code Online (Sandbox Code Playgroud)
如果连接已建立,但发送回数据需要超过60秒,则会发生超时.那样就好.然而,我遇到的行为是我没有得到错误.会话只发出一个新请求."再次给我数据".我不知道发生了什么.不在我的代码中,也没有调用我知道的委托方法.我只能访问服务器日志.它需要服务器大约68秒才能发回数据,但应用程序只是忽略它,因为它正在等待新请求.
一种解决方案是增加超时值.但我不喜欢它,它只适用于iOS 7.不是iOS 8.
sessionConfig.timeoutIntervalForRequest = 10 * 60.0;
Run Code Online (Sandbox Code Playgroud)
有没有人对此有任何见解?我在stackoverflow上找到了关于后台会话超时问题的链接.这是10个月大,但没有解决方案,只有人同意.
从iOS8开始,如果服务器没有响应,则后台模式下的NSUrlSession不会调用此委托方法.-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
下载/上传无限期保持空闲状态.当服务器没有响应时,在iOS7上调用此委托时出错.
通常,如果线路出现问题,NSURLSession后台会话不会使任务失败.相反,它继续寻找运行请求并在那时重试的好时机.这将一直持续到资源超时到期(即,用于创建会话的NSURLSessionConfiguration对象中的timeoutIntervalForResource属性的值).该值的当前默认值为一周!换句话说,iOS7中超时失败的行为是不正确的.在后台会话的上下文中,由于网络问题而不立即失败更有趣.因此,自iOS8以来,NSURLSession任务即使遇到超时和网络丢失也会继续.然而,它会一直持续到达timeoutIntervalForResource.
所以基本上timeoutIntervalForRequest在后台会话中不起作用,但是timeoutIntervalForResource会起作用.
来源:Apple论坛
无法阻止自己,这是你的答案有点重构:)
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
NSURLSessionConfiguration *sessionConfig;
float timeout = 5 * 60.0f;
BOOL iOS8OrNewer = [[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0;
if (iOS8OrNewer) {
sessionConfig = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:identifier];
request.timeoutInterval = timeout;
}
else {
sessionConfig = [NSURLSessionConfiguration backgroundSessionConfiguration:identifier];
sessionConfig.timeoutIntervalForRequest = timeout;
}
_backgroundSession = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];
NSURLSessionDownloadTask *downloadTask = [_backgroundSession downloadTaskWithRequest:request];
Run Code Online (Sandbox Code Playgroud)
我设法解决了它。我并不是说我的解决方案就是解决方案,但它确实是解决方案。
我遇到的情况是 iOS 7 和 iOS 8 对属性的优先级不同。我有两个地方可以设置这些超时属性:NSURLSessionConfiguration和NSMutableURLRequest。iOS 7 不太关心 requests 属性,iOS 8 也不太关心配置属性。现在我的解决方案如下所示:
NSURLSessionConfiguration *sessionConfig;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
sessionConfig = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:identifier];
}
else {
sessionConfig = [NSURLSessionConfiguration backgroundSessionConfiguration:identifier];
}
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) {
sessionConfig.timeoutIntervalForRequest = 5 * 60.0;
}
_backgroundSession = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
request.timeoutInterval = 5 * 60.0;
}
NSURLSessionDownloadTask *downloadTask = [_backgroundSession downloadTaskWithRequest:request];
Run Code Online (Sandbox Code Playgroud)
我想人们可以不进行系统版本检查并将这两个属性设置为相同的值。尽管我坚信代码越少越好,但我更坚信不影响不需要受影响的状态。不过我很想听听人们的意见。如果有人有更好的解决方案请分享。
哦,还有一件事。根据文档,重试部分将持续发生,直到 timeoutIntervalForResource 达到默认值 7 天。我已将其缩短至 10 分钟。
sessionConfig.timeoutIntervalForResource = 10 * 60;
Run Code Online (Sandbox Code Playgroud)
我并不是说应该改变它。这是我们针对特定环境设置做出的决定。
更新
我们将 timeoutIntervalForResource 更改回默认值 7 天。例如,我们在中国有客户,其中一些客户的网络连接非常差。10 分钟的大师限制实在是太愚蠢了。
请务必查看Sunkas 答案以获得更好的代码质量。然而,我的代码片段分布在不同的类中,因此我无法 100% 重用该方法。
| 归档时间: |
|
| 查看次数: |
5645 次 |
| 最近记录: |