Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSCachedURLResponse willCacheResponse does not get called

We have set up a simple NSURLConnection and NSURLCache as per the abbreviated code snippet below. We have made sure, that the server (localhost:9615) returns the following caching headers:

ETag : abcdefgh
Cache-Control : public, max-age=60

However, the willCacheResponse delegate method is never called. Any idea?

Code:

// In the app delegate
NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:20 * 1024 * 1024 diskPath:nil];
[NSURLCache setSharedURLCache:URLCache];

// Triggered by a UIButton
- (IBAction)sendRequest:(UIButton *)sender {
    NSLog(@"sendRequest");
    NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://localhost:9615"] cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:60.0];
    NSMutableData *receivedData = [NSMutableData dataWithCapacity: 0];
    NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
    if (!theConnection) {
        receivedData = nil;
    }
}

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse
{
    NSLog(@"willCacheResponse");
    // ...
}
like image 897
Ralf Avatar asked Mar 25 '26 11:03

Ralf


1 Answers

Cocoa applies all sorts of criteria to determine whether it can cache. For example, in my experience, you will not see willCacheResponse called if the size of the response exceeds roughly 5% of the persistent storage cache size. I've also seen others claim that if max-age is smaller than 1835400, it won't cache either (this is not my experience, but perhaps older iOS versions suffered from this). Obviously, the request has to be a http or https request, not ftp or file request.

If my cache is large enough (and my response correctly supplies Cache-Control and Content-Type), I find that the cache works properly. I only wish that Apple would clearly articulate the criteria being applied (either in documentation or return codes) as I and others have wasted hours diagnosing cache failures only to realize that Cocoa was applying some secret rules.

Note, if NSURLConnection was, itself, satisfied by retrieving it from cache, willCacheResponse will not be called. And, of course ensure that didFailWithError was not called.

like image 144
Rob Avatar answered Mar 27 '26 00:03

Rob