我编写了一个 NSURLProtocol
,它将检查出站 http
请求与 URL 到本地路径映射的 plist
并提供本地内容,然后使用 NSURLCache:
- (void)startLoading
{
//Could this be why my responses never come out of the cache?
NSURLResponse *response =[[NSURLResponse alloc]initWithURL:self.request.URL
MIMEType:nil expectedContentLength:-1
textEncodingName:nil];
//Get the locally stored data for this request
NSData* data = [[ELALocalPathSubstitutionService singleton] getLocallyStoredDataForRequest:self.request];
//Tell the connection to cache the response
[[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowed];
//Have the connection load the data we just fetched
[[self client] URLProtocol:self didLoadData:data];
//Tell the connection to finish up
[[self client] URLProtocolDidFinishLoading:self];
}
我将可以提取本地数据的次数限制为一次。第一次获取它的意图将来自 NSBundle
,但此后它将使用库存 NSURLCache
来检查它是否应该来自 NSURLCache
strong>缓存或网络:
+ (BOOL)canInitWithRequestNSURLRequest *)request
{
//Check if we have pre-loaded data for that request
ELAPathSubstitution* pathSub = [[ELALocalPathSubstitutionService singleton] pathSubForRequest:request];
//We don't have a mapping for this URL
if (!pathSub)
return NO;
//If it's been fetched too many times, don't handle it
if ([pathSub.timesLocalDataFetched intValue] > 0)
{
//Record that we refused it.
[pathSub addHistoryItem:ELAPathSubstitutionHistoryRefusedByProtocol];
return NO;
}
//Record that we handled it.
[pathSub addHistoryItem:ELAPathSubstitutionHistoryHandledByProtocol];
return YES;
}
可悲的是,本地数据似乎会进入缓存,但永远不会回来。这是一个日志片段:
History of [https://example.com/image.png]:
[2014-04-29 18:01:53 +0000] = [ELAPathSubstitutionHistoryHandledByProtocol]
[2014-04-29 18:01:53 +0000] = [ELAPathSubstitutionHistoryHandledByProtocol]
[2014-04-29 18:01:53 +0000] = [ELAPathSubstitutionHistoryHandledByProtocol]
[2014-04-29 18:01:53 +0000] = [ELAPathSubstitutionHistoryCacheMiss]
[2014-04-29 18:01:53 +0000] = [ELAPathSubstitutionHistoryDataFetched]
[2014-04-29 18:01:53 +0000] = [ELAPathSubstitutionHistoryAddedToCache]
[2014-04-29 18:02:11 +0000] = [ELAPathSubstitutionHistoryRefusedByProtocol]
[2014-04-29 18:02:11 +0000] = [ELAPathSubstitutionHistoryRefusedByProtocol]
[2014-04-29 18:02:11 +0000] = [ELAPathSubstitutionHistoryCacheMiss]
[2014-04-29 18:02:11 +0000] = [ELAPathSubstitutionHistoryAddedToCache]
[2014-04-29 18:02:50 +0000] = [ELAPathSubstitutionHistoryRefusedByProtocol]
[2014-04-29 18:02:50 +0000] = [ELAPathSubstitutionHistoryCacheHit]
我的期望是,在第一次被协议(protocol)拒绝后,它会导致几次缓存命中,但它总是将其视为未命中,从服务器获取内容,然后我开始获取缓存命中。
我担心我的 NSURLProtocol
子类以一种允许它们被缓存的方式构造它的响应,但阻止它们被拉出缓存。有什么想法吗?
提前致谢。
与 URL 加载系统的缓存交互是 NSURLProtocolClient
对象的职责,该对象充当 NSURLProtocol
的客户端。如果请求使用 NSURLRequestUseProtocolCachePolicy
作为缓存策略,则由协议(protocol)实现应用正确的特定于协议(protocol)的规则来确定是否应缓存响应。
协议(protocol)实现,在任何适合协议(protocol)的点,调用URLProtocol:cachedResponseIsValid:
在它的客户端上,表明缓存的响应是有效的。然后客户端应该与 URL 加载系统的缓存层进行交互。
但是,由于系统为我们提供的客户端是私有(private)且不透明的,您可能希望自己处理事务并与协议(protocol)中的系统缓存进行交互。如果你想走这条路,你可以直接使用 NSURLCache 。第一步是在你的协议(protocol)中覆盖 -cachedResponse
。如果您仔细阅读文档,默认实现仅根据传递给初始化程序的值设置它。覆盖它以便它访问 shared URL cache (或您自己的私有(private) URL 缓存):
- (NSCachedURLResponse *) cachedResponse {
return [[NSURLCache sharedURLCache] cachedResponseForRequest:[self request]];
}
现在,在您通常会在客户端调用 cachedResponseIsValid:
的地方,也将 NSCachedURLResponse
存储到 NSURLCache
中。例如,当您有完整的字节集和响应时:
[[NSURLCache sharedURLCache] storeCachedResponse:cachedResponse forRequest:[self request]];
关于ios - 如何使用 NSURLCache 缓存由 NSURLProtocol 提供的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23374675/
欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) | Powered by Discuz! X3.4 |