2009-12-08 11 views
11

Estoy intentando descubrir cómo usar el marco de carga de URL para cargar URL aprovechando el almacenamiento en caché.¿NSURLConnection se aprovecha de NSURLCache?

Estoy usando NSURLConnections y les proporciono NSURLRequests. Incluso he configurado el cachePolicy en esas solicitudes a NSURLRequestReturnCacheDataElseLoad. La primera vez que cargo una solicitud, automáticamente se pone en el caché ([NSURLCache sharedCache] lo tiene). Pero la próxima vez que cargue la misma solicitud, NSURLConnection parece ignorar lo que hay en la caché y volver a cargar los datos.

¿Se supone que debo implementar manualmente las búsquedas en caché y devolver los datos en caché? ¿NSURLConnection no hace esto? ¿O hay alguna forma de conseguir que el framework use el cache sin problemas?

ACTUALIZACIÓN: intentado lo siguiente sin éxito:

  • Configuración de la directiva de solicitud de caché para NSURLRequestReturnCacheDataElseLoad en lugar de NSURLRequestUseProtocolCachePolicy
  • reutilizar el objeto de la petición en lugar de hacer una nueva
  • Usando +[NSURLConnection sendSynchronousRequest:returningResponse:error:] en lugar de cargar de forma asíncrona
+2

¿Los está alimentando con el mismo objeto NSURLRequest? La documentación indica que NSURLCache funciona al mapear un objeto específico NSURLRequest a los datos de respuesta especificados, por lo que es posible que incluso si está realizando una solicitud a la misma URL, aún se produzca un error en la caché. – ImHuntingWabbits

+0

No, estoy haciendo una nueva solicitud de NSURL. Pero cuando hago '[[NSURLCache sharedURLCache] cachedResponseForRequest:]' con ese nuevo objeto de solicitud, hay una respuesta en caché. Entonces NSURLCache sabe de alguna manera que las solicitudes son las mismas. – jasoncrawford

+0

PD: intenté reutilizar el objeto NSURLRequest. No hace la diferencia – jasoncrawford

Respuesta

0

It ind El uso de NSURLCache es automático, al menos en algunas circunstancias. Ciertamente lo hace en el siguiente código:

EDITAR - trabajos en una aplicación OS X 10.6 cacao, no iPhone (pregunta mala lectura)

#import <Foundation/Foundation.h> 

int main (int argc, const char * argv[]) { 

    // run request with default cache policy 
NSMutableURLRequest *req=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://en.wikipedia.org/"]]; 
NSData *data=[NSURLConnection sendSynchronousRequest:req returningResponse:nil error:nil]; 
NSLog(@"Received %d bytes", [data length]); 

sleep(10); 

    // now run it asking it to use the cache 
[req setCachePolicy:NSURLRequestReturnCacheDataElseLoad]; 
data=[NSURLConnection sendSynchronousRequest:req returningResponse:nil error:nil]; 
NSLog(@"Received %d bytes", [data length]); 

    return 0; 
} 
+0

Interesante, gracias. Sin embargo, por lo que vale, estoy haciendo solicitudes asíncronas, no estoy seguro si eso importa. – jasoncrawford

+0

OK, así que en realidad probé esto, y no funciona para mí. La segunda solicitud aún tarda varios cientos de milisegundos, y si uso la política de caché 'NSURLRequestReturnCacheDataDontLoad', devuelve 0 bytes. Además, si consulto el caché directamente en el medio usando '[[NSURLCache sharedURLCache] cachedResponseForRequest: req]', devuelve nil. Así que no hay almacenamiento en caché aquí para mí. Me estoy ejecutando en el simulador de iPhone, simulando OS 3.0 (también intenté 3.1.2), bajo Snow Leopard. – jasoncrawford

+1

Correcto, podría tener algo que ver con que estoy ejecutando directamente bajo OS X. No identifiqué la etiqueta de iphone, lo siento. –

0

has necesitado jugar con el método connection:willCacheResponse:? De acuerdo con el URL Loading System documentation, "de manera predeterminada, los datos de una conexión se almacenan en caché según el soporte proporcionado por la subclase NSURLProtocol que maneja la solicitud. Un delegado Delegación NSULConnection puede refinar aún más ese comportamiento implementando la conexión: willCacheResponse :."

+1

Sí, he intentado implementar 'connection: willCacheResponse:' --no ayuda. Ese método se llama, y ​​- aquí está el truco - la respuesta definitivamente termina en el caché. Después de la primera solicitud, '[[NSURLCache sharedCache] cachedResponseForRequest: request]' devuelve la respuesta en caché. Pero si luego inicializo un NSURLConnection con la misma solicitud, se recupera de nuevo en lugar de presionar el caché. – jasoncrawford

+0

Sé que en el pasado he echado un vistazo al caché y eso me ayudó, aunque en esa situación particular quería que el método volviera inmediatamente en lugar de cargarlo de manera asíncrona, si es posible. –

6

NOTA iOS 5 en adelante proporcionan una sharedURLCache que tiene tanto la capacidad memoria y el disco.

Nada va a almacenar en caché a menos que se establezca el NSURLCache que tienen una cierta capacidad:

// A 10MB cache. This a good avatar-image-cache size but might be too 
// large for your app's memory requirements. YMMV. 
[[NSURLCache sharedURLCache] setMemoryCapacity:1024*1024*10]; 

La instancia predeterminada iPhone NSURLCache se niega a alguna caché en el disco. si necesita este comportamiento, debe subclase NSURLCache e implementar su propio caché de disco. He encontrado numerosos ejemplos de cachés de disco en GitHub, aunque ninguno de ellos hace el paso "prune" totalmente necesario satisfactoriamente en mi humilde opinión.

+1

Parece que [[NSURLCache sharedURLCache] setMemoryCapacity: 1024 * 1024 * 10] funciona, pero debe llamarlo cada vez que realiza la solicitud porque cuando lo llamé una vez en mi AppDelegate, el comportamiento de la caché fue totalmente aleatorio entre lanzamientos de la aplicación (alguna vez funcionó, a veces no). –

+0

Incluso si no configura un caché explícitamente, NSURLCache aún crea un archivo db y aún guarda el contenido. – Abhinit

+1

@Abhinit sí, mi respuesta es anterior a iOS 5. Desde entonces, el caché siempre está configurado a menos que lo desactives. – mxcl