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.
Related
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.
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.
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.
I actually have more than one question regarding this... I'm still new to NSURLCache and UIWebViews but somehow got the basics down I think.
Anyway, I was able to successfully implement Caching for my UIWebView(I think). I initialized the NSURLCache. My UIWebView loads its contents with the loadRequest: method. I assigned the ViewController that owns the UIWebView as it's delegate. I also had the ViewController implement NSURLConnectionDataDelegate. I implemented the connection:willCacheResponse: method just to log a message in the console so I could check that caching was done. I also logged the current disk and memory usage. It increases after the caching so I can see that it did work.
However, when I load the page again, I think the request is sent again to the server because the connection delegate methods like connection:didReceiveResponse: and connection:willCacheResponse are being called.
I also wanted to try getting the cachedResponse from the cache by using cachedResponseForRequest:. I called this method in webViewDidFinishLoad: but it always returns null. Did caching really work?
How can you tell if the WebView loaded from the cache? Am I misusing cachedResponseForRequest:? And on another note, what proper Control-Cache header values should be present in the very least for caching? I'm testing on google's homepage URL and it returns the private value for its Cache Control header but I can see that caching works because the connection:willCacheResponse: is called.
Help please?
If you run a HTTP proxy like Charles or Fiddler you can keep tabs on what network traffic is actually going out over the wire(less).
You can also inspect the request/response headers to see whether the response is indeed destined for the cache.
Note that in some cases you might see a conditional-GET (returns a 304) meaning the client asked for content that it has in its cache, but only wants to download the content if the server has a more recent version.
I am downloading WMS tiles which I want to cache. I'm using AFNetworking which includes NSURLCache. The responses from the server do not contain Cache-Control protocols in the header.
I asked the server guy about this and was unfamiliar with server side cache-control. At the moment, he is swamped with other work. Do I need him to implement the cache-control or can I force NSURLCache to cache them w/out the info the response header?
Is NSURLCache persistent? If so, how can I clear the cache? The tiles will need to be retrieved per session and can not be persistent.
Or should I create my own cache?
When you activate NSURLCache it will work for any request that is based on the NSUrlRequest (like AFNetworking). The moment you activate the NSURLCache you can specify it's maximum size. You can also clear the cache by calling the removeAllCachedResponses or removeCachedResponsesForRequest methods. If the server does not send any cache control information, then the cache will still cache the file. If you want complete control over the cache, you could create your own cache. If you would like to see a sample code for that, then have a look at https://github.com/evermeer/EVURLCache