In my application I am using Webview and loading a data which I am getting from the webserver. In this it's working fine but issue is I used NSURLRequest object for sending request to the server. And I wrote the code as such below
NSMutableURLRequest * webPageRequest=[NSMutableURLRequest requestWithURL:webPageUrl cachePolicy:2 timeoutInterval:60.0];
Here the data is caching in memory successfully. But issue is when ever I open app it is always giving old data. It's not sending a request to the server for new data and even the app data is also not updating. I am supporting both IOS6 & IOS7.
So can you please let me know how to resolve this issue. And may I know how long the data will be available in Cache memory. And how NSURLRequestReturnCacheDataElseLoad will work means at what situation this method will execute.
The issue you can see the old data is because the NSURLRequestReturnCacheDataElseLoad, see this (it has been taken from NSHister:
NSURLRequestReturnCacheDataElseLoad: Existing cached data should be
used, regardless of its age or expiration date. If there is no
existing data in the cache corresponding to the request, the data is
loaded from the originating source.
Check out this link you should find the way to use right policy for your purpose.
Related
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 NSUrlConnection to grab some data from a web service that returns JSON data when I hit a url but sometimes the page goes down or something is wrong.
Is there a way to use the cached version of the url in my iOS App to grab that data when the webpage returns a 404?
In the browser if I go to cache:mysite.com/test.php I can see the JSON data even when the page is down but when I try to use the same url in my iOS App, I do not get the JSON data back.
Is there maybe an Obj C class I am not aware of or an option for the NSUrlConnection?
NSURLConnection already uses a cache. By default it only caches responses in-memory, you can customize this by setting it to also use on-disk storage:
NSURLCache *result = [[NSURLCache alloc] initWithMemoryCapacity:[(1024*1024*512) diskCapacity:(1024*1024*1024 * 100) diskPath#"Cache.db"]:
[NSURLCache setSharedURLCache:result];
The reason you are seeing the behavior you describe in your question is that the remote web service is telling your client not to cache the response. You can check this using REDbot or a tool like Charles. By default NSURLRequest will use the protocol's caching policy and semantics, which is almost always the correct thing to do. You can specify a different cache policy by changing the cachePolicy property of the NSURLRequest.
After much search, I didn't find a way to get a cached version of a web page in my iOS app but I handled the 404 error by looking for the response status code and using a service like Google Cache or archive.org/web/ to get the cached version of the url if a 404 was found.
Might not be the most delicate way but I could not find another way to get a cached version of the website when making the request.
I'm using NSURLCache (AFNetworking) to cache responses from my backend, setting Cache-Control = max-age=3600, public. This is working fine so far. When the user opens the app and the data is not older than one hour, it obtains it from the cache. When older, it loads it from the backend.
I also have a pull to refresh option that allows the user to get fresh data from the backend by overriding the cache even though it still has valid cached data, what also works fine.
The problem I have is, that the newly retrieved data (by overriding the cache) doesn't get cached. Scenario is like this:
User opens the app and data with timestamp x is being loaded from the backend with Cache-Control = max-age=3600, public
User studies the data for 10 minutes.
User now does a manual refresh of the data and new data with timestamp y is being pulled from the backend with Cache-Control = max-age=3600, public
User studies the new data for another 10 minutes and closes the app.
User opens the app again, but sees data with timestamp x instead of data with timestamp y
It seems to me that NSURLCache just doesn't cache data from the same resource as long as it has valid cached data, even though fresh data from the same resource came in in the meantime. Does anyone know how to tell NSURLCache to cache the most recent retrieved data even if it still has valid data? Or is it just working as designed? Any help is highly appreciated.
You did not write what code did you use for the manual refresh. I guess you have used NSURLRequestReloadIgnoringCacheData policy. I have not tested if stores the updated response in the cache. However if it does not store it, I would use
removeCachedResponseForRequest: on shared NSURLCache and then load the data as usual.
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.