¿Es posible evitar que un NSURLRequest almacene en caché los datos o elimine los datos en caché después de una solicitud?

StackOverflow https://stackoverflow.com/questions/405151

  •  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!

¿Fue útil?

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top