您可以通过实现自己的
NSURLProtocol
来强制缓存,而不遵循标准的HTTP缓存规则。这里有一个
完整的教程,它使用Core Data持久化数据,但基本步骤如下:
- 子类化
NSURLProtocol
- 使用
+registerClass:
注册您的子类
- 如果这是您第一次看到
request
,则在您的+canInitWithRequest:
方法中返回YES
,否则返回NO
现在您有两个选择:
- 实现自己的缓存存储(在这种情况下,请遵循上面链接的教程)
- 注入您希望URL加载系统遵循的缓存控制头
假设您想要#2,那么请在您的协议子类中覆盖connection:didReceiveResponse:
以创建一个具有您想要模拟的缓存控制头的响应:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response {
NSMutableDictionary *newHeaders = [response.allHeaderFields mutableCopy];
newHeaders[@"Cache-Control"] = @"no-transform,public,max-age=300,s-maxage=900";
NSHTTPURLResponse *newResponse = [[NSHTTPURLResponse alloc] initWithURL:response.URL
statusCode:response.statusCode
HTTPVersion:@"HTTP/1.1"
headerFields:newHeaders];
[self.client URLProtocol:self
didReceiveResponse:newResponse
cacheStoragePolicy:NSURLCacheStorageAllowed];
}
这将导致响应被缓存,就像服务器提供了这些标头一样。
仅适用于URL会话,您需要设置会话配置的protocolClasses。由于您正在使用AFNetworking,因此看起来像这样:
对于URL会话,您需要设置会话配置的protocolClasses
。由于您正在使用AFNetworking,所以代码如下:
[AFHTTPSessionManager sharedManager].session.configuration.protocolClasses = @[[MyURLProtocol class]]
有一些注意事项,所以请确保您阅读protocolClasses
文档。
一些注意事项:
- 如果有办法通过让您的服务器发送适当的标头来修复此问题,请务必这样做。
- 为简洁起见,我硬编码了“HTTP / 1.1”,但从技术上讲,您应该从响应中提取它。
- AFNetworking使用标准的URL加载系统,与此问题大多无关。
NSMutableURLRequest
的cachePolicy
属性。 - fluidsonic