2014-08-30 11 views
7

È possibile forzare il caching della risposta se non contiene né Expires o Cache-Control: max-age?AFNetworking 2.0 - Caching forzato

Mi sono imbattuto nell'articolo this, ma sfortunatamente URLSession:dataTask:willCacheResponse:completionHandler: non viene mai chiamato nella sottoclasse AFHTTPSessionManager.

Qualsiasi aiuto apprezzato.

+0

È possibile utilizzare il [ 'cachePolicy'] (https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSMutableURLRequest_Class/index.html#//apple_ref/occ/instp/NSMutableURLRequest/cachePolicy) proprietà di 'NSMutableURLRequest'. – fluidsonic

risposta

6

È possibile forzare la memorizzazione nella cache implementando il proprio NSURLProtocol che non segue le regole di caching HTTP standard. Un complete tutorial is here, che persiste i dati utilizzando Core Data, ma i passaggi fondamentali sono:

  • sottoclasse NSURLProtocol
  • Pubblica il tuo sottoclasse con +registerClass:
  • ritorno YES nel metodo +canInitWithRequest: se questa è la prima volta che si' ho visto request, o NO se non è

ora avete due scelte:

  1. implementare il proprio sistema di memorizzazione (in tal caso, seguire il tutorial linkato sopra)
  2. Iniettare le intestazioni di controllo della cache che si desidera che il sistema di URL di carico di seguire

Supponendo che si desidera # 2, override connection:didReceiveResponse: nella sottoclasse protocollo per creare una risposta che ha le intestazioni di controllo della cache che si desidera emulare:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response { 
    // Create a dictionary with the headers you want 
    NSMutableDictionary *newHeaders = [response.allHeaderFields mutableCopy]; 
    newHeaders[@"Cache-Control"] = @"no-transform,public,max-age=300,s-maxage=900"; 

    // Create a new response 
    NSHTTPURLResponse *newResponse = [[NSHTTPURLResponse alloc] initWithURL:response.URL 
                   statusCode:response.statusCode 
                   HTTPVersion:@"HTTP/1.1" 
                   headerFields:newHeaders]; 


    [self.client URLProtocol:self 
      didReceiveResponse:newResponse 
      cacheStoragePolicy:NSURLCacheStorageAllowed]; 
} 

Questo farà sì che la risposta a mettere in cache se il server aveva fornito esimo queste intestazioni


Per le sessioni URL solo, è necessario impostare il protocolClasses configurazione di sessione. Dal momento che si sta utilizzando AFNetworking, che assomiglia:

[AFHTTPSessionManager sharedManager].session.configuration.protocolClasses = @[[MyURLProtocol class]] 

Ci sono alcune avvertenze, quindi assicuratevi di read the protocolClasses documentation.


Alcune note:

  • se c'è un modo per risolvere questo avendo il server invia le intestazioni appropriate, per favore, si prega di fare che, invece.
  • Per brevità ho codificato "HTTP/1.1", ma tecnicamente dovresti escludere questa risposta.
  • AFNetworking utilizza il sistema di caricamento URL standard ed è per lo più non correlato a questo problema.
+0

grazie mille!Sono appena tornato in città, scaverò in questo domani e poi ti assegnerò la taglia. –

+0

@ Ben Cool, fammi sapere se hai qualche domanda. –

+0

ha tutto questo impostato, ma per qualche motivo startLoading non viene mai chiamato sulla sottoclasse NSURLProtocol anche quando restituisco YES da canInitWithRequest. entrambi i metodi verranno richiamati durante il caricamento delle immagini, ma startLoading non viene chiamato quando si caricano richieste alla mia API. mai visto? –