Я написал NSURLProtocol
, который будет проверять исходящие http
запросы по plist
URL-адресам для сопоставления локальных путей и вместо этого обслуживать локальный контент, а затем кэшировать его с помощью 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
, чтобы проверить, должен ли он поступать из кэша или из сети< /сильный>:
+ (BOOL)canInitWithRequest:(NSURLRequest *)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]
Я ожидаю, что после первого отказа протокола это приведет к паре попаданий в кеш, но вместо этого он всегда считает это промахом, извлекает содержимое с сервера, а затем после этого я начинаю получать попадания в кеш.
Я боюсь, что мой подкласс NSURLProtocol
строит свои ответы таким образом, что позволяет кэшировать их, но предотвращает их извлечение из кэша. Любые идеи?
Заранее спасибо. :)