68

I have used UIWebview to load a web page using loadRequest: method, when I leave that scene I call [self.webView stopLoading]; and release the webView.

In activity monitor on first launch i have seen that the real memory increased by 4MB, and on multiple launches/loading the real memory doesn't increase. It is increasing only once.

I have checked the retain count of webview. It is proper i.e., 0. I think UIWebView is caching some data. How do I avoid caching or remove cached data? Or is there another reason for this?

Chandan Shetty SP
  • 5,087
  • 6
  • 42
  • 63

9 Answers9

128

I actually think it may retain cached information when you close out the UIWebView. I've tried removing a UIWebView from my UIViewController, releasing it, then creating a new one. The new one remembered exactly where I was at when I went back to an address without having to reload everything (it remembered my previous UIWebView was logged in).

So a couple of suggestions:

[[NSURLCache sharedURLCache] removeCachedResponseForRequest:NSURLRequest];

This would remove a cached response for a specific request. There is also a call that will remove all cached responses for all requests ran on the UIWebView:

[[NSURLCache sharedURLCache] removeAllCachedResponses];

After that, you can try deleting any associated cookies with the UIWebView:

for(NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]) {

    if([[cookie domain] isEqualToString:someNSStringUrlDomain]) {

        [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
    }
}

Swift 3:

// Remove all cache 
URLCache.shared.removeAllCachedResponses()

// Delete any associated cookies     
if let cookies = HTTPCookieStorage.shared.cookies {
    for cookie in cookies {
        HTTPCookieStorage.shared.deleteCookie(cookie)
    }
}
Peter DeWeese
  • 18,141
  • 8
  • 79
  • 101
groomsy
  • 4,945
  • 6
  • 29
  • 33
  • And what about loadHTMLString:baseURL: ? It doesn't seem to be working when I delete cookies & URL cache... – nverinaud Apr 24 '12 at 07:56
  • 11
    Hi, I tried [[NSURLCache sharedURLCache] removeAllCachedResponses];, but it doesn't work, i still have the same image in cache... Is there another workaround ? – arlg Sep 05 '13 at 15:27
  • 3
    Yeah same here, I'm getting persistent login and I'm thinking the UIWebView may be holding the token too long. Any thoughts? – Ethan Parker Feb 17 '14 at 21:45
  • 1
    Does this work in iOS 7 because from past few days i am stuck with the same issue, i used the above code but nothing happens i still see the cached pages in my webview. Any suggestions on this @groomsy – user2538944 Jun 13 '14 at 14:08
  • 1
    Clearing the NSURLCache didn't help me with iOS7, but I have a hack-ish workaround involving NSURLProtocol. http://stackoverflow.com/a/26408420/449161 – Ben Flynn Oct 16 '14 at 15:41
  • as far as persistent logins go, that's all about cookies not cache. – colin lamarre Feb 24 '15 at 04:05
45

Don't disable caching completely, it'll hurt your app performance and it's unnecessary. The important thing is to explicitly configure the cache at app startup and purge it when necessary.

So in application:DidFinishLaunchingWithOptions: configure the cache limits as follows:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{   
    int cacheSizeMemory = 4*1024*1024; // 4MB
    int cacheSizeDisk = 32*1024*1024; // 32MB
    NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:@"nsurlcache"];
    [NSURLCache setSharedURLCache:sharedCache];

    // ... other launching code
}

Once you have it properly configured, then when you need to purge the cache (for example in applicationDidReceiveMemoryWarning or when you close a UIWebView) just do:

[[NSURLCache sharedURLCache] removeAllCachedResponses];

and you'll see the memory is recovered. I blogged about this issue here: http://twobitlabs.com/2012/01/ios-ipad-iphone-nsurlcache-uiwebview-memory-utilization/

ToddH
  • 2,801
  • 2
  • 28
  • 28
10

You can disable the caching by doing the following:

NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
[sharedCache release];

ARC:

NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
InsertWittyName
  • 3,930
  • 1
  • 22
  • 27
  • In my case I did not need any caching at all so this answer was very helpful to me. For others who choose this direction: These lines are placed within the didFinishLaunchingWithOptions as well. The last line (sharedCache release) should be omitted in newer applications as ARC will handle this for you now. – Isilher Aug 04 '20 at 11:38
6

Swift 3.

// Remove all cache 
URLCache.shared.removeAllCachedResponses()

// Delete any associated cookies     
if let cookies = HTTPCookieStorage.shared.cookies {
    for cookie in cookies {
        HTTPCookieStorage.shared.deleteCookie(cookie)
    }
}
inokey
  • 5,434
  • 4
  • 21
  • 33
CodeOverRide
  • 4,431
  • 43
  • 36
  • This would be better as an edit to another answer since it is just a different language for a question that does not specify a language. – Peter DeWeese Sep 20 '17 at 12:55
  • Works perfectly to clear cache session if you are using api + token and webview + authentication inside the same app! – Pelanes Mar 05 '19 at 08:04
3

I could not change the code, so I needed command line for testing purpose and figured this could help someone:

Application specific caches are stored in ~/Library/Caches/<bundle-identifier-of-your-app>, so simply remove as below and re-open your application

rm -rf ~/Library/Caches/com.mycompany.appname/

JamesWebbTelescopeAlien
  • 3,547
  • 2
  • 30
  • 51
2

My educated guess is that the memory use you are seeing is not from the page content, but rather from loading UIWebView and all of it's supporting WebKit libraries. I love the UIWebView control, but it is a 'heavy' control that pulls in a very large block of code.

This code is a large sub-set of the iOS Safari browser, and likely initializes a large body of static structures.

  • But when i release the webview it suppose to release the cached content also... But it is not releasing the cached content.... How to remove the cached data – Chandan Shetty SP Apr 01 '11 at 05:12
  • Reading your original post, the symptom is that your memory use is going up, but then not dropping when you stop using UIWebView. My suggestion is that the memory use is NOT caches content, but rather the code and data structures loaded by UIWebView. Check that you nave released the UIWebView control, not just the web content you displayed. – Chris Hawkins Apr 03 '11 at 04:21
1

After various attempt, only this works well for me (under ios 8):

NSURLCache *cache = [[NSURLCache alloc] initWithMemoryCapacity:1 diskCapacity:1 diskPath:nil];
[NSURLCache setSharedURLCache:cache];
Blasco73
  • 2,980
  • 2
  • 24
  • 30
1

For swift 2.0:

let cacheSizeMemory = 4*1024*1024; // 4MB
let cacheSizeDisk = 32*1024*1024; // 32MB
let sharedCache = NSURLCache(memoryCapacity: cacheSizeMemory, diskCapacity: cacheSizeDisk, diskPath: "nsurlcache")
NSURLCache.setSharedURLCache(sharedCache)
Infinite Recursion
  • 6,511
  • 28
  • 39
  • 51
sebspi
  • 41
  • 5
0

I am loading html pages from Documents and if they have the same name of css file UIWebView it seem it does not throw the previous css rules. Maybe because they have the same URL or something.

I tried this:

NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
[sharedCache release];

I tried this :

[[NSURLCache sharedURLCache] removeAllCachedResponses];

I am loading the initial page with:

NSURLRequest *appReq = [NSURLRequest requestWithURL:appURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0];

It refuses to throw its cached data! Frustrating!

I am doing this inside a PhoneGap (Cordova) application. I have not tried it in isolated UIWebView.

Update1: I have found this.
Changing the html files, though seems very messy.

Community
  • 1
  • 1
Evgeni Petrov
  • 1,313
  • 13
  • 28
  • Update2: I have managed to deal with this. Right after making new request I also reload the webview. For some reason this loads the css correctly. – Evgeni Petrov Nov 08 '12 at 18:17
  • Hey I know this is old, but what do you mean reload the webview? Calling [webview reload] doesn't seem to do anything and I am in the same position you were, have tried everything and don't want to add a random string to every script and css url. – user1234 Feb 04 '15 at 22:50
  • That was 2012 on iOS6, probably the hack is not working anymore. Just after load I called reload. That was it. – Evgeni Petrov Feb 05 '15 at 15:12