È possibile impedire a una richiesta NSURL di memorizzare i dati nella cache o rimuovere i dati memorizzati nella cache in seguito a una richiesta?

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

  •  03-07-2019
  •  | 
  •  

Domanda

Su iPhone, eseguo una richiesta HTTP utilizzando NSURLRequest per un blocco di dati. Picchi di allocazione degli oggetti e assegnerò i dati di conseguenza. Quando finisco con i dati, li libero di conseguenza - tuttavia gli strumenti non mostrano alcun dato che è stato liberato!

La mia teoria è che, per impostazione predefinita, le richieste HTTP vengono memorizzate nella cache, ma non voglio che la mia app per iPhone memorizzi nella cache questi dati.

Esiste un modo per svuotare questa cache dopo una richiesta o impedire in primo luogo la memorizzazione di dati nella cache?

Ho provato a utilizzare tutti i criteri di cache documentati un po 'come di seguito:

NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
theRequest.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;

ma nulla sembra liberare la memoria!

È stato utile?

Soluzione

Di solito è più facile creare la richiesta in questo modo

NSURLRequest *request = [NSURLRequest requestWithURL:url
      cachePolicy:NSURLRequestReloadIgnoringCacheData
      timeoutInterval:60.0];

Quindi creare la connessione

NSURLConnection *conn = [NSURLConnection connectionWithRequest:request
       delegate:self];

e implementa la connessione: willCacheResponse: metodo sul delegato. Solo il ritorno a zero dovrebbe farlo.

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {
  return nil;
}

Altri suggerimenti

Ho lo stesso problema nella mia app quando ho richiesto informazioni da Twitter. Nel mio caso non avevo bisogno di conservare quelle credenziali, quindi le ho semplicemente cancellate usando il codice seguente:

- (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];
    }
}

Spero che funzioni per qualcuno :)

Se usi NSURLConnection dai un'occhiata al delegato:

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse

Valore di ritorno

La risposta cache effettiva da archiviare nella cache. Il delegato può restituire cachedResponse non modificato, restituire una risposta cache modificata o restituire nulla se non è necessario memorizzare una risposta cache per la connessione.

Se non specifico per una singola richiesta (U vuoi disabilitare la cache per l'intera app) sotto una è l'opzione migliore. Aggiungi questo codice in delegato dell'app o in base alle tue necessità ovunque

        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];

Se stai usando NSURLSession , un'altra soluzione per impedire che richieste e parametri vengano scritti nel Cache.db iOS crea all'interno del Caches directory, è impostare NSURLCache per la configurazione della sessione su una memoria 0 dimensioni e cache disco 0 dimensioni ad es.

let configuration = URLSessionConfiguration.default    
configuration.urlCache = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil)
let session = URLSession(configuration: configuration)

o come menzionato sopra impostato a livello di cache globale

URLCache.shared = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil)

Presumibilmente è lo 0 per la dimensione del disco che interrompe la scrittura su disco di iOS, ma se hai una politica per reloadIgnoringLocalCacheData probabilmente non sei interessato nemmeno alla memorizzazione nella cache della memoria.

Nota Ciò impedirà qualsiasi cartella Caches / Cache.db (richieste e risposte) o Caches / fsCachedData / (dati di risposta) essendo stato creato affatto. Abbiamo deciso di adottare questo approccio in un'app per motivi di sicurezza poiché non vogliamo che le nostre richieste vengano archiviate nella cache del disco.

Se qualcuno sa che c'è un modo per interrompere solo la memorizzazione nella cache delle richieste ma mantenere la memorizzazione nella cache dei dati di risposta dal meccanismo di caricamento dell'URL di iOS, sarei interessato a saperlo. (non c'è API o documentazione ufficiale su questo da quello che posso dire)

NSMutableURLRequest* request = [[NSMutableURLRequest alloc] url];
[request setValue:@"no-store" forHTTPHeaderField:@"Cache-Control"];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];

Supponendo che il server sia correttamente implementato, mettendo l'intestazione Cache-Control: no-store nella richiesta genererà una risposta del server con la stessa intestazione, causando quindi NSURLCache per non memorizzare i dati di risposta sul disco.

Pertanto, non è necessario l'approccio del fucile da caccia per disabilitare la cache del disco NSURLCache .

PS: l'aggiunta dell'intestazione dovrebbe funzionare per tutti i framework HTTP, come AFNetworking

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top