URLSession and URLCache not working as expected

For a GET request which is consistently the same, I'm returning in the response this response header.

Cache-Control: max-age=3600, private

I'm creating a URLSession with this configuration. Basically, ensuring my cache is large. The URLSession persists throughout the life of the app and all requests go through it.

 var configuration = URLSessionConfiguration.default  
        let cache = URLCache(memoryCapacity: 500_000_000,
                               diskCapacity: 1_000_000_000)
        configuration.urlCache = cache
        configuration.requestCachePolicy = .useProtocolCachePolicy

I create a data task with the completion handler:

let task = session.dataTask(with: request) { data, response, error in

//... my response handling code here
}
task.resume()

There isn't anything complicated or unusual I'm doing. I've used this code for years, and I'm now trying to optimise some calls with a caching policy.

So I have 2 issues:

  1. Requests that have no-cache policy are still being saved into the URLCache. Which I've confirmed by looking into URLCache.shared.cachedResponse . Why is it caching them when the response explicitly states no-cache policy and I've told the session to use the protocol policy.

  2. On the request where I do want to use the cache, when I call session.dataTask on subsequent times, it never fetches from the cache. It always hits the server again - which I can confirm from the server logs.

What piece of this am I missing here?

Replies

Requests that have no-cache policy are still being saved into the URLCache. Which I've confirmed by looking into URLCache.shared.cachedResponse . Why is it caching them when the response explicitly states no-cache policy and I've told the session to use the protocol policy.

Based on my understanding of no-cache, I do not think it's wrong to store the response in the cache. The client application just needs to make sure that it's fetching an updated response each time. Is it fetching an updated response each time?

Regarding:

On the request where I do want to use the cache, when I call session.dataTask on subsequent times, it never fetches from the cache. It always hits the server again - which I can confirm from the server logs.

Is the client doing a HEAD call to the server to determine if the cache is expired or not? See the flow chart here.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com