我正在使用新的NSURLSession API并允许用户下载文件。我想尝试告诉我的NSURLSession要同时运行多少次下载,但我没有办法做到这一点。我想尽量避免自己管理下载任务,如果我可以告诉系统有多少允许,那会更好 - 这对于排队后台下载以及我的应用程序未运行时会更好。有没有办法做到这一点?
答案 0 :(得分:19)
您可以使用NSURLSessionConfiguration
属性在HTTPMaximumConnectionsPerHost
对象中设置它。
答案 1 :(得分:13)
我找到了这个超时的解决方法。
尝试在设备上下载具有慢速连接模拟的文件(设置 - >开发人员 - >网络链接调节器 - >选择配置文件 - > 3G - >启用)。
以下是我的示例代码:
- (void) methodForNSURLSession{
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
_tasksArray = [[NSMutableArray alloc] init];
sessionConfig.HTTPMaximumConnectionsPerHost = 3;
sessionConfig.timeoutIntervalForResource = 120;
sessionConfig.timeoutIntervalForRequest = 120;
NSURLSession* session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];
// data tasks
[self createDownloadTasksWithSession:session];
}
- (void) createDownloadTasksWithSession:(NSURLSession *)session{
for (int i = 0; i < 100; i++) {
NSURLSessionDownloadTask *sessionDownloadTask = [session downloadTaskWithURL: [NSURL URLWithString:@"https://discussions.apple.com/servlet/JiveServlet/showImage/2-20930244-204399/iPhone%2B5%2BProblem2.jpg"]];
[_tasksArray addObject:sessionDownloadTask];
[sessionDownloadTask addObserver:self forKeyPath:@"countOfBytesReceived" options:NSKeyValueObservingOptionOld context:nil];
[sessionDownloadTask resume];
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if([[change objectForKey:@"old"] integerValue] == 0){
NSLog(@"task %d: started", [_tasksArray indexOfObject: object]);
}
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
if (!error) {
NSLog(@"task %d: finished!", [_tasksArray indexOfObject:task]);
} else if (error.code == NSURLErrorTimedOut) {
NSLog(@"task %d: timed out!", [_tasksArray indexOfObject:task]);
}
}
我的输出:
2014-01-10 10:38:48.769 TestApplication[2442:1803] task 1: started
2014-01-10 10:38:49.517 TestApplication[2442:1803] task 2: started
2014-01-10 10:38:50.273 TestApplication[2442:4b03] task 0: started
2014-01-10 10:40:11.794 TestApplication[2442:5003] task 2: finished!
2014-01-10 10:40:13.924 TestApplication[2442:1803] task 3: started
2014-01-10 10:40:26.221 TestApplication[2442:1d0f] task 1: finished!
2014-01-10 10:40:28.487 TestApplication[2442:1d0f] task 4: started
2014-01-10 10:40:43.007 TestApplication[2442:440f] task 5: timed out!
2014-01-10 10:40:43.009 TestApplication[2442:440f] task 6: timed out!
2014-01-10 10:40:43.011 TestApplication[2442:440f] task 7: timed out!
...
正如您所看到的,任务在2分钟后开始超时
我使用了timeoutIntervalForResource
和timeoutIntervalForRequest参数,如果我们将两者都设置为0,它将在没有超时的情况下下载。但我觉得这不是一个好主意,因为电池已经被吸引了。我认为10分钟或类似的东西对它来说是一个很好的价值。但您必须将两个参数都设置为相同的值。
Apple docs:
timeoutIntervalForRequest
- 等待时使用的超时间隔 用于其他数据。timeoutIntervalForResource
- 最高金额 应该允许资源请求的时间。(超时) 所有任务到一个资源)
注意到奇怪的事情:如果我们设置timeoutIntervalForResource = 60
和timeoutIntervalForRequest = 30
,任务将在30秒后超时!但他们中的大多数甚至都不会开始!
当任务恢复时,看起来timeoutIntervalForRequest
的计时器已启动。在这种情况下,我们在同一时间内恢复所有任务,每个任务的超时必须是资源超时。
另外,我可以为wwdc13 705 session提供一个关于下载任务后台会话的精彩演示。