6

Using NSURLSession's default caching, how do I invalidate the cache for a particular URL?

I note NSURLCache's removeCachedResponseForRequest: method, but that takes an NSURLRequest object, which I don't have for the original request. Do I need to store those as I create them so I can then pass them back into removeCachedResponseForRequest: or can I just create a new one with the appropriate URL which will then serve as equivalent for the purpose, even if it doesn't have the same header fields and other properties as the original?

Robert Atkins
  • 23,528
  • 15
  • 68
  • 97

3 Answers3

5

If you want to go further you could reset the cached response for the url request you want to force the reload. Doing the following:

let newResponse = NSHTTPURLResponse(URL: urlrequest.URL!, statusCode: 200, HTTPVersion: "1.1", headerFields: ["Cache-Control":"max-age=0"])
let cachedResponse = NSCachedURLResponse(response: newResponse!, data: NSData())
NSURLCache.sharedURLCache().storeCachedResponse(cachedResponse, forRequest: urlrequest)

As the cache-control header of the response hax a max age of 0 (forced) the response will never be returned when you do this request.

Your answer works fine for forcing a single request, but if you want to have two versions of the request one forcing and another relying on the cached response, removing the cached one once you force a request is desired.

Felipe Jun
  • 722
  • 11
  • 22
  • Out of curiosity, did this actually work for you? I'm trying to use this method of manually resetting the cached response with Swift 2.2 on iOS 9.3. However, doing `NSURLCache.sharedCache().cachedResponseForRequest(...)` still returns a cached response. – Clay Ellis Aug 02 '16 at 22:09
  • @ClayEllis well, the last version of the app is running 2.2 and is working fine in production, i have no access to the code anymore though. Are you setting the cache control header to have a life of zero? – Felipe Jun Aug 02 '16 at 22:22
  • Yes, I'm doing exactly what you've done above. Would `NSURLCache` ever still return a cached response even though the `max-age` is set to zero? – Clay Ellis Aug 03 '16 at 00:04
  • This doesn't work for me (iOS 10.2) the override cache with empty data is always returned – benrudhart Dec 13 '16 at 08:16
4

The solution turns out not to be invalidating the cache for an existing URL, but to set:

request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;

When you make the next request for the resource you know to be invalid. There are options to ignore the local cache only, or to request that upstream proxies ignore their caches too. See the NSURLRequest/NSMutableURLRequest documentation for details.

Robert Atkins
  • 23,528
  • 15
  • 68
  • 97
  • Be cautious of the other options: [`reloadIgnoringLocalAndRemoteCacheData`](https://developer.apple.com/documentation/foundation/nsurlrequest/cachepolicy/reloadignoringlocalandremotecachedata) and [`reloadRevalidatingCacheData`](https://developer.apple.com/documentation/foundation/nsurlrequest/cachepolicy/reloadrevalidatingcachedata) should never be used: they are **unimplemented** by Apple. – Cœur Nov 05 '18 at 11:01
1

Here's what has been working for me:

request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData

Here are all the options listed regarding chache policy, so you may find one that better suits your need:

enter image description here

Using Swift 2.2 and Xcode 7.3

Andrej
  • 7,266
  • 4
  • 38
  • 57
  • 1
    Be cautious that [`reloadIgnoringLocalAndRemoteCacheData`](https://developer.apple.com/documentation/foundation/nsurlrequest/cachepolicy/reloadignoringlocalandremotecachedata) and [`reloadRevalidatingCacheData`](https://developer.apple.com/documentation/foundation/nsurlrequest/cachepolicy/reloadrevalidatingcachedata) should never be used: it's **unimplemented** by Apple. – Cœur Nov 05 '18 at 11:00
  • @Cœur What do you mean by "it's unimplemented"? It did not work for you? Do you think it's a bug / have you reported it? Because the reference clearly defines how it should behave: https://developer.apple.com/documentation/foundation/nsurlrequest/cachepolicy – Andrej Nov 05 '18 at 11:23
  • 1
    I'm specifically talking about two specific enum cases: follow those two links, and see the doc for yourself, it says: "_**Important** This constant is unimplemented and shouldn’t be used._" – Cœur Nov 05 '18 at 11:33