URLSession and URLRequest
Caching
URLCache
Apple provides a really nice built-in way to do caching, using URLCache
. You can configure a URLSession
object to use your specific cache via URLSessionConfiguration.urlCache
.
Once configured, all requests through that session will use that cache, though it’s possible to override for specific requests, or for all requests from that session.
Note that URLSession.shared
is configured to use URLCache.shared
by default. This is transparent to the user (that is, there’s no easy way to determine whether or not the request actually used the network or returned cached data).
ETag and Manual Caching
Sometimes you want to manually cache responses. Because URLSession
uses a cache by default, we have to tell our requests to not do that. There are a few ways to do that:
- Use a URLSession that isn’t backed by a cache (by creating one with the configuration’s
urlCache
property set to nil) - Use a URLSession with a cache policy that ignores the cache (set the configuration’s
requestCachePolicy
to. reloadIgnoringLocalAndRemoteCacheData
- Have all your
requests
individually specify.reloadIgnoringLocalAndRemoteCacheData
as theircachePolicy
Once you have the caching behavior set, you need to implement manual caching yourself. I’m going to describe using ETag because that’s better (and what my nginx server did for me).
The ETag header is one way to determine whether or not a resource has changed from when it was last served. It’s essentially a hash of the resource information (as opposed to using something like Last-Modified for a time-based approach). You pair this with the If-None-Match request header to have the server calculate whether the data has changed (HTTP 200 response) or not (HTTP 304 response).
So, the algorithm for doing this is:
- Make initial request
- Record the value for the
ETag
(orEtag
) header in the response you send. - In subsequent requests to the same url, include the
If-None-Match
request header, with value set to whatever you received for thatEtag
header.- If you receive a 304:
- Use the older data you had (no cache update needed).
- If you receive a 200:
- Overwrite the etag you had with the newer etag header
- Use the new data you received in the body of the response.
- If you receive a 304:
Last updated: 2020-06-07 16:24:37 -0700