Est-il possible d'empêcher un NSURLRequest de mettre en cache des données ou de supprimer des données en cache suite à une requête?

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

  •  03-07-2019
  •  | 
  •  

Question

Sur iPhone, j'exécute une requête HTTP à l'aide de NSURLRequest pour un bloc de données. Les pics d’allocation d’objets et j’assigne les données en conséquence. Lorsque je termine avec les données, je les libère en conséquence. Cependant, les instruments ne montrent aucune donnée libérée!

Ma théorie est que, par défaut, les demandes HTTP sont mises en cache - je ne veux pas que mon application iPhone mette en cache ces données.

Existe-t-il un moyen d'effacer ce cache après une requête ou d'empêcher la mise en cache de données en premier lieu?

J'ai essayé d'utiliser toutes les stratégies de cache décrites un peu comme ci-dessous:

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

mais rien ne semble libérer la mémoire!

Était-ce utile?

La solution

Généralement, il est plus facile de créer une requête comme ceci

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

Créez ensuite la connexion

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

et implémentez la méthode de connexion: willCacheResponse: sur le délégué. Il suffit de renvoyer zéro pour le faire.

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

Autres conseils

J'ai le même problème dans mon application lorsque j'ai demandé des informations à Twitter. Dans mon cas, je n'avais pas besoin de conserver ces informations d'identification, alors je les efface simplement en utilisant le code suivant:

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

J'espère que cela fonctionnera pour quelqu'un:)

Si vous utilisez NSURLConnection, examinez le délégué:

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

Valeur renvoyée

La réponse mise en cache à stocker dans le cache. Le délégué peut renvoyer cachedResponse sans modification, renvoyer une réponse en cache modifiée ou renvoyer nil si aucune réponse en cache ne doit être stockée pour la connexion.

S'il n'est pas spécifique à une requête unique (vous voulez désactiver le cache de l'application entière), une des options ci-dessous est la meilleure. Ajoutez ce code dans le délégué de l'application ou en fonction de vos besoins

        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 vous utilisez NSURLSession , une autre solution pour empêcher l'écriture de la requête et des paramètres sur Cache.db crée dans Caches répertoire, consiste à définir NSURLCache pour la configuration de la session sur une mémoire de taille 0 et un cache de disque de taille 0 , par exemple

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

ou comme mentionné ci-dessus, défini au niveau du cache global

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

C'est vraisemblablement le 0 pour la taille du disque qui empêche iOS d'écrire sur le disque, mais si vous avez une stratégie pour reloadIgnoringLocalCacheData , la mise en cache de la mémoire ne vous intéresse probablement pas non plus.

Remarque Ceci empêchera tout dossier Caches / Cache.db (demandes et réponses) ou Caches / fsCachedData / (données de réponse) être créé du tout. Nous avons décidé d'adopter cette approche dans une application à des fins de sécurité, car nous ne voulons plus que nos demandes soient stockées dans le cache du disque.

Si quelqu'un sait s'il existe un moyen d'arrêter uniquement la mise en cache des demandes tout en conservant la mise en cache des données de réponse à partir du mécanisme de chargement d'URL iOS, cela m'intéresserait. (il n'y a pas d'API ou de documentation officielle à ce sujet d'après ce que je peux dire)

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

En supposant que le serveur soit correctement implémenté, l'insertion de l'en-tête Cache-Control: no-store dans la requête génèrera une réponse du serveur avec le même en-tête, ce qui entraînera NSURLCache . ne pas stocker les données de réponse sur le disque.

Par conséquent, il n’est pas nécessaire d’adopter une approche simpliste consistant à désactiver la mise en cache du disque NSURLCache .

PS: l'ajout de l'en-tête devrait fonctionner pour tous les frameworks HTTP, comme AFNetworking

.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top