What is the maximum cache size for iOS6 web apps and how can I extend it?

Jules picture Jules · Feb 14, 2013 · Viewed 8.3k times · Source

I'm building a web app especially for the iPad (running iOS 6+) showing the product collection of a company.

It all worked perfectly using HTML5's "cache.manifest" file. But since the cache has grown to about 50MB the iPad is not saving the application data anymore. Instead of 50MB the cache size is now 0.1KB according to the Safari settings.

So what is the actual limit of Safari's cache for a web app and is there a way to enlarge the maximum amount for the application cache?

Answer

mddw picture mddw · Feb 19, 2013

edit 2nd june 2014 : The maximum cache size on iOS7.1 is 300Mb.

A client asked me this precise question recently, so I investigated.

As per IOS6 (all my tests have been done on iOS6.1), these are two different things :

  • a website using a .manifest, accessed with mobile Safari
  • a webapp on the home screen, created from the website

A website with a .manifest can use up to 50mb of cache, with an user permission asked. It can't use more. This value can be found and cleared in settings/safari/advanced. If you try to stuff more in the cache, a error event will be fire and the window.applicationCache.status will go IDLE.

A webapp does not share the same cache than its website. Clearing the cache settings/safari/advanced won't do anything for you home screen webapp. It will accept more than 50mb of cache without user input, but I don't know exactly how much (I tested with 60mb with success, totally accessible offline. *edit : tried with 83mb, success) I don't know where this data can be seen in iOS settings. I guess nowhere.

Testing this was a pain in the *** until I found the spec. There's an API that works perfectly on iOS6.
You should check window.applicationCache.status, which tells you what's the app state, and the following events (cut and paste from my code, so with their listener) :

window.applicationCache.addEventListener('checking', onChecking);
window.applicationCache.addEventListener('noupdate', onNoupdate);
window.applicationCache.addEventListener('downloading', onDownloading);
window.applicationCache.addEventListener('progress', onProgress);
window.applicationCache.addEventListener('cached', onCached);
window.applicationCache.addEventListener('updateready', onUpdateready);    
window.applicationCache.addEventListener('obsolete', onObsolete);
window.applicationCache.addEventListener('error', onError);

All are working on iOS 6.1, even the progress event with event.loaded and event.total

A webapp starts by checking, then fires noupdate if the .manifest is the same. Status is IDLE.

If the .manifest changed, status is DOWNLOADING, the progress event fires for each file in your manifest, then status is UPDATEREADY and the updateready fires.

If you're offline, an error event fires and status is IDLE.

You can test the online/offline status with

var online = navigator.onLine ? 'online' : 'offline';

It works but the specs says it's unreliable.

Three more things to finish :

  • my manifest is named cache.manifest and declared like this <html manifest="cache.manifest">
  • my .htaccess has AddType text/cache-manifest manifest and ExpiresByType text/cache-manifest "access plus 0 seconds"
  • my app has <meta name="apple-mobile-web-app-capable" content="yes">

With this API, it's way easier to understand what's going on under the hood. Be sure to do your own test though, I'm not 100% sure of this results or they can could with a new iOS version. I'll test further for the maximum size.