我正在尝试使用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"]]; }
但是,我需要执行后台下载,我必须使用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"]]; }
来自Apple的This documentation表示NSURLDownloadTasks不调用URLSession:dataTask:willCacheResponse:completionHandler:delegate方法,因此您的应用程序无法挂钩到缓存生命周期.我的猜测是,这意味着缓存根本不适用于这些任务,但对此并不明确.
- For a data task,the
NSURLSession
object calls the delegate’sURLSession:dataTask:willCacheResponse:completionHandler:
method. Your
app should then decide whether to allow caching. If you do not
implement this method,the default behavior is to use the caching
policy specified in the session’s configuration object.
任何人都可以确认这一预感NSURLSessionDownloadTasks根本不支持缓存吗?是否可以在后台任务中利用Apple的HTTP缓存行为?
解决方法
NSURLSessionDownloadTask使用在应用程序进程外执行下载的系统服务(守护程序)执行工作.因此,实际为下载任务调用的委托回调比NSURLSessionDataTask更受限制.如
Life Cycle of a URL Session中所述,数据任务委托将接收回调以自定义缓存行为,而下载任务委托则不会.
下载任务应该使用NSURLRequest指定的缓存策略,并且应该使用NSURLSessionConfiguration指定的缓存存储(如果没有,则提交错误).默认缓存策略为NSURLRequestUseProtocolCachePolicy,默认URL缓存存储是非后台和非短暂配置的共享URL缓存. URLSession的委托回调:dataTask:willCacheResponse:completionHandler:不是实际发生的缓存的好指标.
如果使用默认会话配置创建NSURLSessionDownloadTask并且不自定义NSURLRequests的缓存策略,则缓存已经发生.