我正在尝试使用NSURLSessionDownloadTask,并利用Apple的内置URL缓存功能.NSURLSessionDataTask使用下面的代码时,我已经成功地使缓存工作:
- (void)downloadUsingNSURLSessionDataTask:(NSURL *)url {
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
[dataTask resume];
}
- (void)cachedDataTaskTest {
// This call performs an HTTP request
[self downloadUsingNSURLSessionDataTask:[NSURL URLWithString:@"http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"]];
[NSThread sleepForTimeInterval:1];
// This call returns the locally cached copy, and no HTTP request occurs
[self downloadUsingNSURLSessionDataTask:[NSURL URLWithString:@"http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"]];
}
Run Code Online (Sandbox Code Playgroud)
但是,我需要执行后台下载,我必须使用NSURLDownloadTask.切换到此时,不会发生缓存行为.
- (void)downloadUsingNSURLSessionDownloadTask:(NSURL *)url {
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request];
[downloadTask resume];
}
- (void)cachedDownloadTaskTest {
// This call performs an HTTP request
[self downloadUsingNSURLSessionDownloadTask:[NSURL URLWithString:@"http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"]];
[NSThread sleepForTimeInterval:1];
// This call also performs an HTTP request
[self downloadUsingNSURLSessionDownloadTask:[NSURL URLWithString:@"http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"]];
}
Run Code Online (Sandbox Code Playgroud)
Apple的此文档表明NSURLDownloadTasks不调用URLSession:dataTask:willCacheResponse:completionHandler:委托方法,因此您的应用程序无法挂钩缓存生命周期.我的猜测是,这意味着缓存根本不适用于这些任务,但对此并不明确.
- 对于数据任务,该
NSURLSession对象调用委托的URLSession:dataTask:willCacheResponse:completionHandler:方法.然后,您的应用应决定是否允许缓存.如果未实现此方法,则默认行为是使用会话配置对象中指定的缓存策略.
任何人都可以确认这一预感NSURLSessionDownloadTasks根本不支持缓存吗?是否有可能在后台任务中利用Apple的HTTP缓存行为?
que*_*ish 10
NSURLSessionDownloadTask使用在应用程序进程外执行下载的系统服务(守护程序)执行工作.因此,实际上为下载任务调用的委托回调比那些更有限NSURLSessionDataTask.如URL会话的生命周期中所述,数据任务委托将接收回调以自定义缓存行为,而下载任务委托则不会.
下载任务应该使用由其指定的缓存策略NSURLRequest,并且应该使用指定的缓存存储NSURLSessionConfiguration(如果没有,则提交bug).默认缓存策略是NSURLRequestUseProtocolCachePolicy,默认URL缓存存储是非后台和非短暂配置的共享URL缓存.委托回调URLSession:dataTask:willCacheResponse:completionHandler:并不是实际发生的缓存的良好指标.
如果NSURLSessionDownloadTask使用默认会话配置创建并且不自定义NSURLRequests 的缓存策略,则缓存已经发生.
看起来好像NSURLSessionDownloadTask没有缓存,按设计.
NSURLSessionConfiguration文档
该defaultSessionConfiguration方法记录在案:
默认会话配置使用基于磁盘的持久缓存(除非将结果下载到文件中),并将凭据存储在用户的密钥链中.
但是,没有其他构造函数被记录为排除上述斜体异常.我也测试了backgroundSessionConfigurationWithIdentifier它似乎也没有做到这一点.
此外,requestCachePolicy也没有提供任何出于例外的方法.
NSURLSessionDownloadTask运行时效率
NSURLSessionDownloadTask将传入数据写入临时文件.完成文件后,它会通知委托或完成处理程序.最后它删除文件.
虽然它可以简单地将文件移动到缓存中,但它必须处理委托或完成处理程序实际修改文件,从而更改其缓存的表示,甚至将文件移动到永久位置,它无法跟踪.
它可以在通知委托或完成处理程序之前复制文件,但这对于大文件来说效率低下.
它可以将文件保持为只读,但在iOS 8.0上似乎不会这样做.
因此,系统不太可能对下载任务进行任何缓存.
解决方法
您最好的选择是使用NSURLSessionDataTask,然后在URLSession:dataTask:didReceiveData:调用您的委托方法时,将传入的数据附加到您自己的文件中.下次使用时,NSURLSessionDataTask您可以在一次调用中获取缓存数据URLSession:dataTask:didReceiveData:.
| 归档时间: |
|
| 查看次数: |
2771 次 |
| 最近记录: |