在检查标头(长度和类型)后,我需要使用后台功能下载某些文件(不是全部),但是它必须处于同一操作中,而不是创建新的任务/请求(因为有时我会收到一个由于在短时间内有许多连接,导致服务器出现错误)。因此,我开始执行任务:
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);
}
}
但是,由于数据任务不能使用BackgroundSessionConfiguration,所以我想新创建的下载将使用相同的默认会话配置。如何使该下载在后台运行?有什么办法可以将其会话更改为后台会话吗?还是采用哪种方法?
对我来说,这个问题很难给出明确的答案,因为这三个主要的URLLoading因素(sessionType,taskType,FG / BG创建)都受您的设计限制。
由于session会保留配置的深层副本(确定default / BackGround / Ephemeral session-nature-type),因此在启动会话(在我们的示例中为default-type-Session)后,您将无法修改配置对象本届会议了。因此,如果您的设计不允许将新的Task与一个新的(希望的) BG-type-Session关联,则没有办法只能将“ dataTask”神奇地转换为“ downloadTask”。
请记住,NSURLSessionDataTask和NSURLSessionDownloadTask是的两个子类NSURLSessionTask,NSURLSessionDataTask和NSURLSessionDownloadTask处理传入响应数据(分段VS文件明智分别)非常不同由框架实现。
诱人的错觉可能是这种诱人的方法URLSession:dataTask:didBecomeDownloadTask:
,但是您必须创建一个与当前会话(由先前配置的默认类型加深标记)相关联的新任务(实际上是DownloadTask ),并将原始任务(dataTask)保留为孤立对象。我的理解是,由于额外创建了任务,您的设计不能采用此选项,并且您将不得不使用默认类型的会话配置。
URLSession:dataTask:didBecomeDownloadTask:应该真正命名为URLSession:dataTask:wasReplacedByDownloadTask:
我现在仅有的一个简单解决方案是,在Data-Task-Delegate (类实现NSURLSessionDataDelegate协议)中,当接收URLSession:dataTask:didReceiveData:初始调用时,便开始以某种方式存储这些分段数据(存储到临时文件中,也许,模拟NSURLSessionDownloadTask的默认操作),并确保在NSOperationQueue上异步执行此委托 (我猜您的“背景能力”是指辅助线程,可以由NSOperationQueue强调线程机制提供),直到下载完成,然后检查您的存储累积结果(如果处理任何错误和/或将文件传输到其他位置) 在此一般的NSURLSessionTaskDelegate方法“ URLSession:task:didCompleteWithError:”中
这样做,您可以将请求(由NSURLSessionDataTask表示)转换为下载(而不是NSURLSessionDownloadTask)。为了满足在后台队列上进行的转换,请为此委托方法的最后一个参数(会话/任务)提供一个非null值:-否则,串行操作队列将无法满足您的“后台能力”需求
NSOperationQueue* aQueue = [[NSOperationQueue alloc] init];
NSURLSession *sessione = [NSURLSession sessionWithConfiguration:configuratione delegate:self delegateQueue: aQueue];
其他想法是手动执行多个NSOperation对象,重写它们的启动方法以确保下载任务异步执行,这可能会有些棘手。
其他具有更好解决方案的人,请带来更多火花……或纠正我可能引起的任何误导。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句