Спасибо за лидерство! Это расклеило меня. К сожалению, я, кажется, сталкиваюсь с кучей блокпостов.
Проблема в том, что если я использую NSURLRequestReturnCacheDataDontLoad, я думаю, что загружаемые ресурсы уже должны быть в кэше.
Чтобы поместить их в кеш, я попробовал это:
NSURLRequest *request = [NSURLRequest
requestWithURL:cachedURL
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:60.0] ;
NSURLResponse *responseToCache =
[[NSURLResponse alloc]
initWithURL:[request URL]
MIMEType:@"text/html"
expectedContentLength:[dataAtURL length]
textEncodingName:nil] ;
NSCachedURLResponse *cachedResponse =
[[NSCachedURLResponse alloc]
initWithResponse:responseToCache data:dataAtURL
userInfo:nil storagePolicy:NSURLCacheStorageAllowedInMemoryOnly] ;
// Store it
[[NSURLCache sharedURLCache] storeCachedResponse:cachedResponse forRequest:request] ;
[responseToCache release] ;
[cachedResponse release] ;
NSLog( @"*** request %@, cache=%@", request ,[[NSURLCache sharedURLCache]
cachedResponseForRequest:request] ) ;
Я получил этот код из других источников в сети, но я думаю, что, хотя он работал на Mac, он не работает на iPhone, моей целевой платформе.
Кажется, элемент не помещается в кеш; NSLog печатает ноль для "cache =% @".
Затем я попытался перегрузить NSURLCache:
- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request
{
NSLog( @"FileFriendlyURLCache asked from request %lx of type %@ for data at URL: %@" ,
request , [request class] , [[request URL] absoluteString] ) ;
NSCachedURLResponse *result = nil ;
if( [[[request URL] absoluteString] hasPrefix:@"file://"] )
{
NSLog( @"\tFulfilling from cache" ) ;
NSError *error = nil ;
NSData *dataAtURL = [NSData dataWithContentsOfURL:[request URL]
options:0 error:&error] ;
if( error )
NSLog( @"FileFriendlyURLCache encountered an error while loading %@: %@" ,
[request URL] , error ) ;
NSURLResponse *reponse = [[NSURLResponse alloc]
initWithURL:[request URL]
MIMEType:@"text/html"
expectedContentLength:[dataAtURL length]
textEncodingName:nil] ;
result = [[NSCachedURLResponse alloc] initWithResponse:reponse data:dataAtURL
userInfo:nil storagePolicy:NSURLCacheStorageAllowedInMemoryOnly] ;
#warning LEOPARD BUG MAKES IT SO I DONT AUTORELEASE result NSCachedURLResponse
[reponse release] ;
}
else
{
NSLog( @"\tFulfilling from web" ) ;
result = [super cachedResponseForRequest:request] ;
}
NSLog( @"Result = %@" , result ) ;
return result ;
}
В своем запросе я указываю политику кэширования NSURLRequestReturnCacheDataDontLoad. Этот метод, кажется, называется просто отлично, но он имеет странное поведение на iPhone. Независимо от того, возвращаю ли я экземпляр NSCachedURLResponse, UIWebView по-прежнему возвращает ошибку:
Error Domain=NSURLErrorDomain Code=-1008 UserInfo=0x45722a0 "resource unavailable"
Это как если бы UIWebView игнорировал тот факт, что он получает что-то отличное от nil и в любом случае дает сбой. Затем я заподозрил и подумал, что вся система загрузки URL просто игнорирует все, что приходит из -cachedResponseForRequest, поэтому я создал подкласс NSCachedURLResponse, который выглядит так:
@implementation DebugCachedURLResponse
- (NSData *)data
{
NSLog( @"**** DebugCachedURLResponse data accessed." ) ;
return [super data] ;
}
- (NSURLResponse *)response
{
NSLog( @"**** DebugCachedURLResponse response accessed." ) ;
return [super response] ;
}
- (NSURLCacheStoragePolicy)storagePolicy
{
NSLog( @"**** DebugCachedURLResponse storagePolicy accessed." ) ;
return [super storagePolicy] ;
}
- (NSDictionary *)userInfo
{
NSLog( @"**** DebugCachedURLResponse userInfo accessed." ) ;
return [super userInfo] ;
}
@end
Затем я изменил -cachedResponseForRequest для использования этого класса:
result = [[DebugCachedURLResponse alloc] initWithResponse:reponse data:dataAtURL
userInfo:nil storagePolicy:NSURLCacheStorageAllowedInMemoryOnly] ;
Я установил запрос на использование политики кэширования NSURLRequestUseProtocolCachePolicy и запустил программу. Хотя я вижу, что моя версия -cachedResponseForRequest вызывается и возвращает DebugCachedURLResponses для всех файловых URL, ни одна из моих отладочных функций не вызывается, что говорит о том, что мои экземпляры DebugCachedURLResponse полностью игнорируются!
Итак, я снова застрял. Я не думаю, что у вас есть другие идеи?
Большое спасибо за ваш первый ответ.