¿Es posible evitar que un NSURLRequest almacene en caché los datos o elimine los datos en caché después de una solicitud?
-
03-07-2019 - |
Pregunta
En el iPhone, realizo una solicitud HTTP usando NSURLRequest para una porción de datos. Asignación de objetos picos y asigno los datos en consecuencia. Cuando termino con los datos, los libero en consecuencia, ¡sin embargo, los instrumentos no muestran ningún dato que haya sido liberado!
Mi teoría es que, de manera predeterminada, las solicitudes HTTP se almacenan en caché, sin embargo, no quiero que la aplicación de mi iPhone almacene en caché estos datos.
¿Hay alguna forma de borrar este caché después de una solicitud o evitar que los datos se almacenen en caché en primer lugar?
He intentado usar todas las políticas de caché documentadas un poco como a continuación:
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
theRequest.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
¡pero nada parece liberar la memoria!
Solución
Por lo general, es más fácil crear la solicitud de esta manera
NSURLRequest *request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:60.0];
Luego crea la conexión
NSURLConnection *conn = [NSURLConnection connectionWithRequest:request
delegate:self];
e implementa la conexión: willCacheResponse: método en el delegado. Simplemente devolviendo nada debería hacerlo.
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {
return nil;
}
Otros consejos
Tengo el mismo problema en mi aplicación cuando solicité información de twitter. En mi caso, no necesité conservar esas credenciales, así que simplemente las borro con el siguiente código:
- (void) eraseCredentials{
NSURLCredentialStorage *credentialsStorage = [NSURLCredentialStorage sharedCredentialStorage];
NSDictionary *allCredentials = [credentialsStorage allCredentials];
//iterate through all credentials to find the twitter host
for (NSURLProtectionSpace *protectionSpace in allCredentials)
if ([[protectionSpace host] isEqualToString:@"twitter.com"]){
//to get the twitter's credentials
NSDictionary *credentials = [credentialsStorage credentialsForProtectionSpace:protectionSpace];
//iterate through twitter's credentials, and erase them all
for (NSString *credentialKey in credentials)
[credentialsStorage removeCredential:[credentials objectForKey:credentialKey] forProtectionSpace:protectionSpace];
}
}
Espero que funcione para alguien :)
Si utiliza NSURLConnection, eche un vistazo al delegado:
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse
Valor de retorno
La respuesta en caché real para almacenar en el caché. El delegado puede devolver cachedResponse sin modificar, devolver una respuesta en caché modificada o devolver nil si no se debe almacenar una respuesta en caché para la conexión.
Si no es específico de una sola solicitud (U quiere deshabilitar el caché para toda la aplicación), una de las siguientes es la mejor opción. Agregue este código en el delegado de la aplicación o, según sea necesario, en cualquier lugar
int cacheSizeMemory = 0*4*1024*1024; // 0MB
int cacheSizeDisk = 0*32*1024*1024; // 0MB
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:@"nsurlcache"];
[NSURLCache setSharedURLCache:sharedCache];
Si está utilizando NSURLSession
, otra solución para evitar que la solicitud y los parámetros se escriban en el Cache.db
que iOS crea dentro de la aplicación Caches
directorio, es configurar el NSURLCache
para la configuración de la sesión en una 0 memoria de tamaño y 0 tamaño de caché de disco por ejemplo,
let configuration = URLSessionConfiguration.default
configuration.urlCache = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil)
let session = URLSession(configuration: configuration)
o como se mencionó anteriormente establecido en un nivel de caché global
URLCache.shared = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil)
Es de suponer que es el 0 para el tamaño del disco lo que detiene la escritura de iOS en el disco, pero si tiene una política para reloadIgnoringLocalCacheData
, es probable que tampoco esté interesado en el almacenamiento en memoria caché.
Nota Esto evitará cualquier carpeta Caches / Cache.db
(solicitudes y respuestas) o Caches / fsCachedData /
(datos de respuesta) siendo creado en absoluto. Hemos decidido adoptar este enfoque en una aplicación por motivos de seguridad, ya que no queremos que nuestras solicitudes se almacenen en el caché del disco.
Si alguien sabe es que hay una manera de detener solo la solicitud de almacenamiento en caché, pero mantener el almacenamiento en caché de datos de respuesta desde el mecanismo de carga de URL de iOS, me gustaría saberlo. (no hay API ni documentación oficial sobre esto por lo que puedo decir)
NSMutableURLRequest* request = [[NSMutableURLRequest alloc] url];
[request setValue:@"no-store" forHTTPHeaderField:@"Cache-Control"];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
Suponiendo que el servidor se haya implementado correctamente, al colocar el encabezado Cache-Control: no-store
en la solicitud se generará una respuesta del servidor con el mismo encabezado, lo que provocará que NSURLCache
para no almacenar los datos de respuesta en el disco.
Por lo tanto, no es necesario el enfoque de escopeta para desactivar el almacenamiento en caché del disco NSURLCache
.
PS: Agregar el encabezado debería funcionar para todos los marcos HTTP, como AFNetworking