我可以在iOS上使用NSURLSessionDownloadTask进行HTTP缓存吗?

我正在尝试使用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方法,因此您的应用程序无法挂钩到缓存生命周期.我的猜测是,这意味着缓存根本不适用于这些任务,但对此并不明确.

  1. For a data task,the NSURLSession object calls the delegate’s URLSession: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的缓存策略,则缓存已经发生.

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...