iosnsurlsessionnsurlcache

NSURLSession not using cached responses


I am able to see cached responses when I query NSURLCache directly but when I request the same resource through NSURLSession:dataTaskWithRequest it always queries the server and never gives me the cached response, even with internet disabled.

I configure NSURLCache in application:didFinishLaunchingWithOptions like this:

let URLCache = NSURLCache(memoryCapacity: 20 * 1024 * 1024,
                          diskCapacity: 80 * 1024 * 1024, diskPath: nil)
NSURLCache.setSharedURLCache(URLCache)

Then I am using this code to check the cache and fetch the response:

print("cached response is \(NSURLCache.sharedURLCache().cachedResponseForRequest(request)?.response)")

NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
  print("nsurlsession response \(response)")
}.resume()

The result of my debug prints are:

cached response is Optional(<NSHTTPURLResponse: 0x7f809d0ddfe0> { URL: https://api.test.com/stuff } { status code: 200, headers {
"Cache-Control" = "public, s-maxage=600";
Connection = "keep-alive";
"Content-Type" = "application/json";
Date = "Tue, 06 Sep 2016 23:41:24 GMT";
Etag = "\"4800a836fee27c56a3cce1f0f2bddaefa5a7785b\"";
Server = "nginx/1.11.3";
"Transfer-Encoding" = Identity;
"X-RateLimit-Limit" = 60;
"X-RateLimit-Remaining" = 2; } })

nsurlsession response Optional(<NSHTTPURLResponse: 0x7f809d202e50> { URL: https://api.test.com/stuff } { status code: 200, headers {
"Cache-Control" = "public, s-maxage=600";
Connection = "keep-alive";
"Content-Type" = "application/json";
Date = "Tue, 06 Sep 2016 23:51:52 GMT";
Etag = "\"4800a836fee27c56a3cce1f0f2bddaefa5a7785b\"";
Server = "nginx/1.11.3";
"Transfer-Encoding" = Identity;
"X-RateLimit-Limit" = 60;
"X-RateLimit-Remaining" = 52; } })

As you can see, the Cache-Control headers from the server are set to allow caching. I am not doing anything special with my request, just creating a default NSURLRequest with a URL. Each time I trigger the request, the new response gets cached, but it is never retrieved on subsequent requests.

Is there any reason why NSURLSession would not use a response stored in NSURLCache? Is there something I must do to tell NSURLSession to actually look up requests in the cache?


Solution

  • I can't tell you with absolute certainty why the cache isn't being consulted, but I can give you a list of the most likely reasons:

    I'm probably forgetting several others. With that said, if I'm forgetting them, that probably means that they aren't documented.

    So...

    If you verify that everything listed above is working as expected, file a bug at bugreporter.apple.com and include enough code to reproduce the problem, along with a packet dump if possible.