2014-09-21 16 views
14

Lange Rede, kurzer Sinn, ich habe gerade auf Xcode 6 aktualisiert, um zu sehen, wie meine App auf iOS 8 funktioniert. Ich habe festgestellt, dass der Cache nicht verwendet wird, obwohl er sollte. Ich verwende AFNetworking die cachepolicy wie diese Einstellung:Hat iOS 8 NSURLCache beschädigt?

sessionManager.requestSerializer.cachePolicy = NSURLRequestReturnCacheDataElseLoad; 

ich noch ein iOS-7-Gerät haben, in dem ich den gleichen Code getestet und es funktioniert es wie erwartet.

Hat jemand eine Lösung dafür, oder müssen wir warten, bis Apple es repariert?

+0

Ich habe etwas sehr ähnliches mit NSURLSession bemerkt. Ich denke, dass NSURLConnection noch ordnungsgemäß mit NSURLCache funktioniert. –

+0

Ich habe gerade das gleiche bemerkt (mit AFNetworking2) mit meiner benutzerdefinierten NSURLCache-Unterklasse (storeCachedResponse: forRequest: wird aufgerufen, aber cachedResponseForRequest: wird nie aufgerufen). –

Antwort

12

Ich bin mir fast sicher, dass iOS 8.0 die Fähigkeit NSURLSession hat HTTP-Antwortdaten zu cachen. Ich habe ein Radar mit Apple über dieses Problem geöffnet.

Hier einige Beispiel-Code, den ich schrieb, dies zu beweisen:

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

Auch die Erstellung eigener NSURLSession - mit einem NSURLSessionConfiguration, die eine NSURLCache hat, die Sie selbst erstellen - wird dieses Problem nicht beheben. Für den Fall, dass Sie zwischengespeicherte Antworten dringend benötigen, müssen Sie NSURLConnection verwenden.

+0

Das habe ich mir gedacht. Ich bin erstaunt, wie viele Probleme Apple in letzter Zeit hatte. – Pahnev

+1

Richard, hast du irgendwelche Antworten von Apple über NSURLCache? Ich brauche wirklich Cache in meiner Anwendung, aber es ist in iOS 8 gebrochen ... –

+0

@JohnKakon Habe noch nichts von Apple gehört. Gerade getestet mit Xcode 6.1 GM und es ist immer noch kaputt. Wenn Sie Caching benötigen, müssen Sie NSURLConnection verwenden. –

5

NSURLConnection funktioniert nicht ordnungsgemäß. Es wird die Antworten korrekt speichern, aber es wird never purges the cache (diskCapacity wird ignoriert) auf iOS 8.0, so dass der Cache grow without limit, obwohl manuell Löschen des Cache funktioniert. Dies ist fixed in iOS 8.1, obwohl removeCachedResponseForRequest: immer noch nicht funktioniert.

Wenn Sie eine Cachegröße kleiner als 5 MB angeben, wird nichts zwischengespeichert.

1

Sowohl NSURLCache als auch NSURLSession sind fehlerhaft. Auch wenn Sie NSURLRequestReturnCacheDataElseLoad für die Anforderung festlegen, versucht iOS möglicherweise, die Datei vom Server neu zu laden. Es passiert zum Beispiel, wenn Cache-Antwort Vary Header hat. Beachten Sie auch bitte, dass Verfahren

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

Verwendung User-Agent Header von der Anfrage im Cache gespeicherten Objekte zu unterscheiden. Das bedeutet, dass iOS dieselbe Datei zweimal speichert, wenn Sie auf NSURLSession und UIWebView zugreifen, da anders ist.