2014-09-21 10 views
14

Per farla breve, ho appena aggiornato Xcode 6 per verificare come funziona la mia app su iOS 8. Ho notato che non utilizza la cache anche se dovrebbe. Sto usando l'impostazione AFNetworking l'cachePolicy in questo modo:iOS 8 ha interrotto NSURLCache?

sessionManager.requestSerializer.cachePolicy = NSURLRequestReturnCacheDataElseLoad; 

ho ancora un dispositivo iOS 7 in cui ho provato lo stesso codice e funziona lì come previsto.

Qualcuno ha una soluzione per questo, o dobbiamo aspettare che Apple la risolva?

+0

Ho notato qualcosa di molto simile con NSURLSession. Penso che NSURLConnection stia ancora funzionando correttamente con NSURLCache. –

+0

Ho appena notato lo stesso (con AFNetworking2) con la mia sottoclasse NSURLCache personalizzata (storeCachedResponse: forRequest: viene richiamato, ma cachedResponseForRequest: non viene mai chiamato). –

risposta

12

Sono quasi certo che iOS 8.0 ha interrotto la capacità di NSURLSession di memorizzare nella cache i dati di risposta HTTP. Ho aperto un radar con Apple su questo problema.

Ecco alcuni esempi di codice che ho scritto per dimostrare questo:

NSURLSession *session = [NSURLSession sharedSession]; 
NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 
                diskCapacity:32 * 1024 * 1024 
                 diskPath:nil]; 
[NSURLCache setSharedURLCache:URLCache]; 

dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); 
NSURL *URL = [NSURL URLWithString:@"http://i.imgur.com/b5pyONe.jpg"]; 
NSURLRequest *request = [NSURLRequest requestWithURL:URL 
             cachePolicy:NSURLRequestReturnCacheDataElseLoad 
            timeoutInterval:5]; 
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
    if (error) { 
     NSLog(@"Error occurred"); 
    } else { 
     NSLog(@"Fetched resource!"); 
    } 
    dispatch_semaphore_signal(semaphore); 
}]; 
[task resume]; 

dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 

request = [NSURLRequest requestWithURL:URL 
          cachePolicy:NSURLRequestReturnCacheDataDontLoad 
         timeoutInterval:5]; 
task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
    if (error) { 
     NSLog(@"Something bad happened: %@", error); 
    } else { 
     NSLog(@"Fetched resource!"); 
    } 
}]; 
[task resume]; 

Anche creare il proprio NSURLSession - con una NSURLSessionConfiguration che ha un NSURLCache che si crea da soli - non risolverà questo problema. Per ora, se hai bisogno di risposte memorizzate nella cache male, devi usare NSURLConnection.

+0

Questo è quello che pensavo. Sono stupito di quanti problemi Apple abbia avuto ultimamente. – Pahnev

+1

Richard, hai qualche risposta da Apple su NSURLCache? Ho davvero bisogno di cache nella mia applicazione, ma è rotto in iOS 8 ... –

+0

@JohnKakon Non ho ancora sentito nulla da Apple. Appena testato con Xcode 6.1 GM ed è ancora rotto. Se è necessaria la memorizzazione nella cache, è necessario utilizzare NSURLConnection. –

5

NSURLConnection non funziona correttamente. Memorizzerà le risposte correttamente, ma è never purges the cache (diskCapacity viene ignorato) su iOS 8.0, quindi la cache sarà grow without limit, sebbene la cancellazione manuale della cache funzioni. Questo è fixed in iOS 8.1, sebbene removeCachedResponseForRequest: ancora non funziona.

Inoltre, se si specifica una dimensione della cache inferiore a 5 mega, non verrà memorizzato nella cache nulla.

1

Entrambi NSURLCache e NSURLSession sono bacati. Anche se si imposta NSURLRequestReturnCacheDataElseLoad per richiesta, iOS può provare a ricaricare il file dal server. Accade ad esempio quando la risposta nella cache ha l'intestazione Vary. Inoltre si prega di notare che il metodo

- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request 

uso User-Agent colpo di testa da richiesta di distinguere gli oggetti memorizzati nella cache. Significa che iOS memorizzerà lo stesso file due volte, se ci si accede da NSURLSession e UIWebView, perché User-Agent è diverso.