我有一个应用程序,我正在下载相当多的图像供以后显示。
即使没有互联网连接,应用程序也需要运行,因此图像会在一个点上加载并使用NSURLCache保留。
这是一个简洁的解决方案,因为我可以使用普通网络库并轻松利用自定义缓存设置。
我意识到这种类型的缓存并不保证文件在它们到期之前一直存在,因为只要系统认为有必要就可以释放缓存。这不是一个大问题,因为图像应该能够重新下载并因此重新保留。
但是,我注意到它决定从缓存中随机发布图像,而在我再次下载时似乎不会持续存在。我不确定我哪里出错了。
首先,我像这样定义缓存容量:
NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:50 * 1024 * 1024
diskCapacity:200 * 1024 * 1024
diskPath:@"netcache"];
[NSURLCache setSharedURLCache:URLCache];
(内存50MB,磁盘200MB)
下载图像时(使用AFNetworking)我修改了响应标头以将Cache-Control
设置为max-age=31536000
,这意味着应将响应缓存一年。
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:60.0];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
// Download completed
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// Download failed
}];
[operation setCacheResponseBlock:^NSCachedURLResponse *(NSURLConnection *connection, NSCachedURLResponse *cachedResponse) {
NSURLResponse *response = cachedResponse.response;
NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse*)response;
NSDictionary *headers = HTTPResponse.allHeaderFields;
NSMutableDictionary *modifiedHeaders = headers.mutableCopy;
modifiedHeaders[@"Cache-Control"] = @"max-age=31536000"; // 1 year in seconds
NSHTTPURLResponse *modifiedHTTPResponse = [[NSHTTPURLResponse alloc]
initWithURL:HTTPResponse.URL
statusCode:HTTPResponse.statusCode
HTTPVersion:@"HTTP/1.1"
headerFields:modifiedHeaders];
return [[NSCachedURLResponse alloc] initWithResponse:modifiedHTTPResponse data:cachedResponse.data userInfo:cachedResponse.userInfo storagePolicy:NSURLCacheStorageAllowed];
}];
[self.operationQueue addOperation:operation];
...但似乎图像已经发布,再次下载时甚至不会“重新缓存”。 (我相信它们被报告为缓存,即使它们在设备没有任何连接时尝试显示它们也不会加载。)
稍后使用AFNetworking的UIImageView+AFNetworking.h
类别显示图像,如下所示:
[self.imageView setImageWithURL:url];
有什么想法吗?
答案 0 :(得分:1)
我遇到了同样的问题。首先,您可以使用AFURLSessionManager的方法
- (void)setDataTaskWillCacheResponseBlock:(NSCachedURLResponse * (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSCachedURLResponse *proposedResponse))block;
同时为所有请求设置缓存块。
第二 - 检查' Cache-Control'响应标题中的字段是“公共”字段。例如:
[someAFHTTPSessionManager setDataTaskWillCacheResponseBlock:^NSCachedURLResponse *(NSURLSession *session, NSURLSessionDataTask *dataTask, NSCachedURLResponse *proposedResponse)
{
NSHTTPURLResponse *resp = (NSHTTPURLResponse*)proposedResponse.response;
NSMutableDictionary *newHeaders = [[resp allHeaderFields] mutableCopy];
if (newHeaders[@"Cache-Control"] == nil) {
newHeaders[@"Cache-Control"] = @"public";
}
NSHTTPURLResponse *response2 = [[NSHTTPURLResponse alloc] initWithURL:resp.URL statusCode:resp.statusCode HTTPVersion:@"1.1" headerFields:newHeaders];
NSCachedURLResponse *cachedResponse2 = [[NSCachedURLResponse alloc] initWithResponse:response2
data:[proposedResponse data]
userInfo:[proposedResponse userInfo]
storagePolicy:NSURLCacheStorageAllowed];
return cachedResponse2;
}];
第三:如果图像的大小超过总缓存空间的5%,则不会缓存。此外,似乎还有一些额外的隐藏规则。