I am unable to delete the cache for a request, on top of that I can't use NSURLRequestCachePolicy to Ignore local and remote cache data. What to do?
It seems impossible to just ignore the cache.
Some things that I have tried but they didn't work:
Removing the cache for a specific request
Removing all cache
Creating a request with a ReloadIgnoringLocalAndRemoteCacheData policy
Do you have any suggestions?
The thing that we can't get rid of the cache reminds me of the quote: "Once you go black you never go back".
Answering my own question: Resetting the NSURLSession seems to work, I did that along with having a request with a ReloadIgnoringLocalAndRemoteCacheData policy, I don't know if it will work without that, but in this combination they seem to work.
I have reseted the URLSession with this code: with a ReloadIgnoringLocalAndRemoteCacheData policy
Related
I don't want my App storing any URL data in the cache.db file. I took advice on StackOverflow and set the cache URL policy to NSURLRequestReloadIgnoringLocalCacheData like this.
[manager.requestSerializer setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
However, I'm not sure if there are any issues that can arise from doing this. Any tips or suggestions are appreciated.
Edit: I haven't ran into any issues regarding requests or the App in general, but I like to make sure.
There won't be any issues with this, however you have to ensure, that the named behaviour is really the one you want. E.g. you have a caching mechanism implemented somewhere else.
This policy does exactly what is supposed to do. It ignores any local cache data and loads any data directly from a remote source. However, you're not protected from any intermediate caching mechanisms.
You can include proper headers to your request to omit any intermediate caching (Cache-Control: no-cache to tell some proxies what do you want to do with the request for example)
I've just come across something that has entirely changed my mental image of URLSession caching in iOS.
We were hitting an endpoint that only ever got hit once.
Restarting the app wouldn't hit the endpoint again.
Deleting the app would cause it to hit the endpoint again... but only once.
The header of the response contains...
Cache-Control public, max-age=1800
So it is down to caching. By manually telling the URLSession to ignore the cache it would hit the endpoint again.
In the docs it shows the caching policy and how it works as a workflow diagram.
https://developer.apple.com/documentation/foundation/nsurlrequestcachepolicy/nsurlrequestuseprotocolcachepolicy
But where is the cached data stored once the app is terminated? Surely the app and everything to do with it is removed from memory?
The URLSession is using URLCache for it's caching system. It's used for all network resources. You can access it directly or setting your own through URLSessionConfiguration. The underlying location of the URLCache is on the file system rather than in memory. There is a way to manage cache yourself though. Say, for instance, your response should be encrypted on the device. Slightly bad example, but you get the point. ;)
Here's an article how to manage cache programmatically if you are needing more control over caching.
I am using AFNetworking with NSURLCache. Requests are created with NSURLRequestUseProtocolCachePolicy. App receives responses with headers:
Etag = "1398684731";
Cache-Control = "public";
and everything works perfect. But now I need to add an offline mode.
How it should work:
If internet connection is available everything should work as usual
(application asks back-end for new data and if it has different
Etag new data is downloaded if Etag is the same - cached response
is used).
If there is no internet connection - cached response is
used.
The problem is that in offline mode requests fail.
I have tried to solve this using various Cache-Control options but it seems that it does not work this way.
I have found possible solution here https://stackoverflow.com/a/15885318/3140927 . It should work but it is not very elegant and I think something might have changed in the last year.
Also I have found that "NSURLCache was not made for explicit offline scenarios and that it was designed to speed up Safari and should not be used for manual downloads". Will SDURLCache be better for my purposes?
So what could be the best way to implement offline mode?
It sounds like you want the request to succeed, even though the cache says the data has expired and should be retrieved from the server. You may have some luck setting the cache policy (different policy for online vs. offline) of certain requests where you'd rather use stale data than fail.
Great Link is here->
SDURLCache with AFNetworking and offline mode not working
Today I tried to solve exactly the same problem with this article and it works pretty well: http://blog.originate.com/blog/2014/02/20/afimagecache-vs-nsurlcache/. The key point is here to subclass NSURLCache to make your cache independent from response headers.
I've found couple mistypes in examples, but hope it still will be helpful for you!
I'm curious about NSURLCache, NSURLRequest has some policy of cache,
like NSURLRequestUseProtocolCachePolicy, NSURLRequestReturnCacheDataElseLoad,
but after read them, either of them are using local cache data, or not using cache,
My question is if I want start a url request, first I wanna load cache and render ui, then continue interacting with server to grab latest data and refresh the ui, which policy is my choice?
If I understand correctly what you want to achieve (get data quickly from the cache to show in the UI even if it is outdated, then get the current data even if it is slow), you'd have to make two requests, using different cache policies. I'd start the second request only when the first one has finished, and examine the result of the first request first, because the data might not have been available in the cache, so the first request might already returned the uncached data that you wanted.
I've used NSURLRequestReturnCacheDataElseLoad but it does not work, ie, it always loads data from server as every time the data I received is different.
I'm wondering that:
even with NSURLRequestReturnCacheDataElseLoad policy, it also obeys the cache control headers from server's response, regardless of document saying ignoring expire date?
What is the storage policy for [NSURLCache sharedURLCache]? If it is in memory only, then next time I start the app it won't have cache on disk?
I found this very interesting:
NSURLRequestReturnCacheDataElseLoad not loading from cache on first request?
which says
it seems this problem only exists when there's a query in the url.
Is that a confirmed problem?
Thanks
Well this topic is almost 5 years old, but I just recently had the same problem. In my case, I was using a NSURLSessionDownloadTask which, according to Can I use HTTP caching with an NSURLSessionDownloadTask on iOS?, doesn't use caching no matter which caching policy is used. I switched my code to use NSURLSessionDataTask and the NSURLRequestReturnCacheDataElseLoad policy worked as expected.