14

I'm showing a web app in an UIWebView, and sometimes the content of pages will change. After content have been changed the app clears the cache. But when I go to a page I've previously visited the UIWebView doesn't send a HTTP GET request, but loads from cache even though I've disabled cache like so:

[[NSURLCache sharedURLCache] removeAllCachedResponses];
[[NSURLCache sharedURLCache] setDiskCapacity:0];
[[NSURLCache sharedURLCache] setMemoryCapacity:0];

Initally I'm loading a request with cachePolicy cachePolicy:NSURLRequestReturnCacheDataElseLoad.

[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:myURLString] cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:10.0]];

UIWebView have some kind of internal cache. Already visited pages will be loaded from this internal cache instead of going through NSURLCache and also there's no request sent.

Is there any way to clear the internal cache of UIWebView? I'm even recreating the UIWebView but the cache is still there.

Bartosz Ciechanowski
  • 10,293
  • 5
  • 45
  • 60
Niklas Berglund
  • 3,563
  • 4
  • 32
  • 32
  • Have you try the solution here : http://stackoverflow.com/a/14096331/1749367 – helper Oct 01 '13 at 13:11
  • Yes, no success with any of those solutions works for what I want to accomplish. – Niklas Berglund Oct 13 '13 at 18:49
  • I've found a workaround - setting the Cache-Control attribute in the HTTP response header to max-age=0. Then a request will be sent for the resource every time. A way to solve it could be to keep track of if a file has been requested before since the last cache purge, and set max-age to another value(e.g. 3600) the second time a resource is loaded after the last purge. – Niklas Berglund Oct 13 '13 at 18:53
  • Just realised that this workaround doesn't work, as when a resource is cached it won't be reloaded after cache purge so I then lose control over it. – Niklas Berglund Oct 13 '13 at 19:26
  • @NiklasBerglund were you able to get this resolved? I have tried with all the mentioned options and even the workarounds like adding a random get parameter do not seem to work for me! – Ravi Nov 18 '13 at 16:53
  • 1
    @Ravi no, my conclusion was that there is no way to clear the cache other than restarting the app. Which is how I did it in the end. When cache must be cleared the user is asked to restart the application. They click a button and the app quit itself for the user. – Niklas Berglund Nov 21 '13 at 16:06
  • @NiklasBerglund Thanks for clarifying. Even I had ended up doing something similar. I doubt what HttpWatch iOS app was doing. I have also tried modifying web view cache keys that I saw in NSUserDefaults but did not have any use. Thank you. – Ravi Nov 22 '13 at 05:26

2 Answers2

22

It appears that what's happening here is that it reloads the actual HTML file, but does not necessarily reload the resources within that page.

A possible solution I've seen is to append a query parameter on to the end of the URL. For example:

NSString *testURL = [NSString stringWithFormat:@"%@?t=%@", url, randQuery];
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:testURL] cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:10.0]];

where you generate a random alphanumeric string as your randQuery query parameter, or keep a persistent count and just count up.

This should force the UIWebView to load from the remote resource.

Community
  • 1
  • 1
Joel Fischer
  • 6,521
  • 5
  • 35
  • 46
  • I don't want to disable caching completely though. Sorry, my use of NSURLRequestReloadIgnoringLocalAndRemoteCacheData is confusing. Will update the question. Actually using cachePolicy:NSURLRequestReturnCacheDataElseLoad. Want it to be cached until I purge the cache. – Niklas Berglund Oct 13 '13 at 19:21
  • Then it sounds like you'll just have to use the server side, you could possibly use AJAX requests or Web Sockets when the content changes rather than trying to refresh the page. Would that possibly work in your situation? – Joel Fischer Oct 13 '13 at 19:34
  • Good idea, but not suitable in my case. Another company created the web app. I can modify it though, but the web app has already been built. – Niklas Berglund Oct 13 '13 at 19:47
  • Hmmm I guess I could append a string at the end of URI's. A string that is unique per cache purge. Then the web app would have to append this string like some-resource.html?lastpurge=1381693741. To all references to resources. – Niklas Berglund Oct 13 '13 at 19:50
  • Yeah, that sounds a lot like I proposed above, just instead of doing a random string on every refresh, you build a string for each cache-purge. That might give you the control you're looking for. – Joel Fischer Oct 13 '13 at 20:22
  • @NiklasBerglund Did this method work for you? Any chance I can still get the bounty? – Joel Fischer Oct 20 '13 at 18:20
  • Thanks for the answer, but I did not mark it as a correct answer as it doesn't answer my question how to clear the cache but instead offers a workaround. It was automatically awarded half the bounty as it's the answer with the most upvotes. – Niklas Berglund Oct 25 '13 at 10:25
  • Ended up asking the user to restart the app for all changes to take effect. – Niklas Berglund Oct 25 '13 at 10:27
  • it doesn't work for me when I try to reload a local web resource. Probably, it works only for the remote request? – chipbk10 Mar 23 '15 at 10:14
7

I had the same issue and setting HTTPShouldHandleCookies property to NO fixed my problem.

For example:

NSMutableURLRequest  *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:strurl]];

[request setHTTPShouldHandleCookies:NO];

[webView loadRequest: request];

Hope this help.

Katerina
  • 71
  • 1