2012-01-27 8 views
9

Sembra che UIWebView non chiami sempre storeCachedResponse:forRequest: ogni volta che carica una risorsa. Qualcuno sa perché? Sto cercando di memorizzare le immagini usando -[NSURLCache storeCachedResponse:forRequest:], fa la maggior parte del lavoro, tuttavia in alcuni casi UIWebView non chiama questo metodo sul caricamento della pagina in cui ci sono effettivamente immagini su di esso.UIWebView non chiama sempre [NSURLCache storeCachedResponse: forRequest:]

+0

ho notato anche questo; anche se solo * su * dispositivo per la mia app. Quando la visualizzazione Web carica una richiesta da NSURLCache, sembra saltare quella stessa cache per le risorse su quella pagina. – Nevir

risposta

4

Come descritto hereNSURLConnection non chiama storeCachedResponse:forRequest: se la dimensione del file supera 50kb (52428 byte).
Prova ASIHTTPRequestcaching.

+0

Lo vedo anche per i file di piccole dimensioni (100s di byte). Anche la webview non riesce a chiamare 'cachedResponseForRequest:' – Nevir

+0

@Nevir Vedere [risposta] (http://stackoverflow.com/a/9968398/517815). :) – MrGomez

2

Hai controllato lo stato HTTP e le intestazioni della cache? Scade, Cache-Control ecc.? Forse un server risponde con status = 304 senza alcun corpo di risposta?

- (void)connection:(NSURLConnection *)conn didReceiveResponse:(NSURLResponse *)aResponse 
{ 
    NSLog(@"CODE: %d", ((NSHTTPURLResponse *)aResponse).statusCode); 
    NSLog(@"HEADERS: %@", ((NSHTTPURLResponse *)aResponse).allHeaderFields); 
} 
10

Rispondendo interrogazione del provider di taglie:

sto vedendo questo per file di piccole dimensioni (100s di byte) pure. Il WebView riesce anche a chiamare cachedResponseForRequest:

ho trovato this question che risolve questo comportamento direttamente:

Nonostante la documentazione indicating otherwise di Apple, NSURLCache su iOS non fa alcun disco (flash) il caching a tutti . È possibile sottoclasse NSURLCache per modificare il comportamento delle operazioni di recupero e negozio per utilizzare il disco (come SDURLCache fa), ma a causa della seguente gravi limitazioni di come la cache viene utilizzato e implementato, questo non lo fa funzionare così come ci si aspetta:

  • NSURLConnection non ha nemmeno chiamare storeCachedResponse:forRequest: per i file su circa 50 KB (> = 52428 byte, per l'esattezza). Questo rende la sottoclasse NSURLCache inutile per il nostro uso (200KB di immagini), perché non sarà nemmeno possibile accedere alla cache. Come risultato , dobbiamo aggiungere la cache manualmente a un livello superiore a NSURLConnection.

  • Anche quando si chiama il NSURLCache incorporato storeCachedResponse:forRequest: manualmente, memorizza solo la risposta nella memoria se è inferiore a circa 180KB. Ho provato questo da chiamando storeCachedResponse manualmente e vedendo che il prima/dopo currentMemoryUsage non è cambiato per le lunghezze di dati superiori a circa 180 KB. Quindi dobbiamo scrivere anche il nostro caching della memoria LRU.

(l'enfasi è mia.)

Questo sembra essere responsabile del comportamento di essere chiamato fuori. Come the current accepted answer points out, ASIHTTPRequest è la soluzione alternativa prevista per questo comportamento.

Tuttavia, nota l'avvertimento nella parte superiore della pagina:

Si prega di notare che io non sono più sto lavorando su questa libreria - si consiglia di considerare l'utilizzo di qualcosa di diverso per i nuovi progetti. :)

È consigliabile fare affidamento su librerie supportate o, se si preferisce, contribuire nuovamente a questa libreria una volta sottostata al codice.

+1

Apprezzalo :) (E un grande esempio di dove avrei dovuto cercare di più) - grazie per aver dedicato del tempo a scavare a fondo in questo! – Nevir

+0

@Nevir Nessun problema! Sono felice che sia stato utile. :) – MrGomez

+0

Qualcuno sa se questo è ancora il caso con NSURLSession su iOS 7/8? Sto riscontrando problemi nell'ottenere NSURLCache per salvare file di immagine grandi (~ 7MB). –

2

Non sono sicuro di come funziona per un UIWebvieuw, ma quando si utilizza un NSURLRequest la dimensione massima del file dipende da come si inizializza l'Urlcache (initWithMemoryCapacity: (NSUInteger) memoryCapacity ...) ho appena memorizzato nella cache un file di 2MB

+0

Per me, un file .css da 515 KB richiesto da UIWebView può essere trattato con 'cachedResponseForRequest:' di una sottoclasse 'NSURLCache' inizializzata con' memoryCapacity: 0 diskCapacity: 1024 * 1024 * 256' – hiroshi

3

NSURLCache opere con due cache diverse: cache cache e in memoria su disco

  • le risposte verranno memorizzati nella cache cache in memoria se la dimensione di risposta è sotto 50kb e
  • Le risposte verranno memorizzati nella cache cache su disco se la dimensione di risposta è oltre 50kb

Se si inizializza NSURLCache con diskPath nil poi la cache su disco non sarà attivo e storeCachedResponse:forRequest: sarà chiamato solo per dimensioni di risposta inferiori a 50kb.

Quindi configurare l'urlcache come questo

[[MYCustomURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 
          diskCapacity:20 * 1024 * 1024 
          diskPath:@"urlcache.db"];