我需要在检查标题(对于长度和类型)后,使用后台才能下载某些文件(不是所有文件),但它必须处于相同的操作中,而不是创建新的任务/请求(因为有时候由于在很短的时间内连接很多,我从服务器收到错误。 所以我开始任务:
NSURLSessionConfiguration *configuratione = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *sessione = [NSURLSession sessionWithConfiguration:configuratione delegate:self delegateQueue:nil];
NSURLSessionDataTask *datatask = [sessione dataTaskWithRequest:request];
[datatask resume];
然后,我知道可以在收到第一个响应时将数据任务转换为下载任务,并使用此委托:
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
{
if(XXXXXXXXXX){
NSLog(@"transform into a download");
completionHandler(NSURLSessionResponseBecomeDownload);
}else{
NSLog(@"Keep loading normally");
completionHandler(NSURLSessionResponseAllow);
}
}
但是,由于Data Tasks无法使用BackgroundSessionConfiguration,我认为新创建的下载将使用相同的默认会话配置。 如何在后台运行下载?有没有办法将它的会话改为后台会话?或者哪种方法?
答案 0 :(得分:10)
这个问题很难给出一个明确的答案,对我来说,所有3个主要的URLLoading因素(sessionType,taskType,FG / BG创建)都受到你的设计的限制。
由于会话在配置(确定默认/ BackGround / Ephemeral会话 - 自然类型)上保留了深层副本,因此在启动会话后(在我们的情况下:您的默认值 - type-Session)你不能再修改当前会话的配置对象。因此,如果您的设计不允许新的任务与新的(希望) BG类型会话相关联,那么就没有办法只能神奇地转换" dataTask"进入" downloadTask"。
请注意, NSURLSessionDataTask 和 NSURLSessionDownloadTask 都是 NSURLSessionTask 的子类,NSURLSessionDataTask和NSURLSessionDownloadTask处理传入的响应数据(分别为VS文件)框架实现的方式非常不同。
一个有吸引力的错觉可能是这种有吸引力的方法URLSession:dataTask:didBecomeDownloadTask:
,但您必须创建一个与当前相关联的新任务(DownloadTask in deed)(由您之前配置的深刻标记)默认类型)会话,并将原始任务(dataTask)保留为孤儿。我的理解是,由于额外创建任务,您的设计不能采用此选项,并且您必须保持默认类型会话配置。
URLSession:dataTask:didBecomeDownloadTask:应该真正命名为URLSession:dataTask:wasReplacedByDownloadTask:
我现在只有简单的解决方案是,在接收URLSession时,在Data-Task-Delegate (类实现NSURLSessionDataDelegate协议):dataTask:didReceiveData:初始调用,开始存储这些分段数据某种方式(存储到临时文件,也许,模拟NSURLSessionDownloadTask的默认操作),并确保在NSOperationQueue上异步执行此委托 (我猜你的"后台能力"表示辅助线程,可以由NSOperationQueue提供,强调线程机制),直到下载完成,然后检查存储中的累积结果(如果处理任何错误和/或者将文件转移到其他地方在这个通用的NSURLSessionTaskDelegate方法" URLSession:task:didCompleteWithError:"
这样做,您将请求(由NSURLSessionDataTask表示)转换为下载(不是NSURLSessionDownloadTask) 。为了满足此转换发生在后台队列上,为(委托/任务)此委托方法的最后一个参数提供非零值: - 否则,串行操作队列将无法满足您的"后台能力& #34;需要
NSOperationQueue* aQueue = [[NSOperationQueue alloc] init];
NSURLSession *sessione = [NSURLSession sessionWithConfiguration:configuratione delegate:self delegateQueue: aQueue];
其他想法将手动执行多个NSOperation对象,覆盖其启动方法以确保下载任务的异步执行,这可能有点棘手。
任何其他有更好解决方案的人,请带来更多火花......或纠正我可能产生的任何误导。