How to create offline webapps on the iPhone
Recently Google launched their latest mobile version of Gmail optimised for iPhone and Android based browsers. One of the features that stood out was the offline access thanks to the browsers support of html5 application cache.
Documentation on the application cache feature supported in safari iPhone 2.1+ is scarce and of that documentation it doesn’t go into great detail. The best place to learn about this is on the Safari DevCenter under the mobile section, there it has 2 documents introducing the user to offline webapps; the first is a quick rundown on just the manifest file and the second article touches on a few more features available to offline webapps such as the javascript events for updating the cache when the user is online. We’ll delve into these later in the article but first let’s take a look at a working example.
To see the offline webapp in action, load the demo on your iPhone, then turn Airplane Mode on, re-open Safari and reload the demo. This time it will fetch the files from the cache that was created on the initial load.
How does it all work?
To get a basic offline webapp up and running is incredibly simple but it does have one caveat which tends to get a lot of people frustrated quickly when for some reason the offline feature isn’t working. We’ll explain that issue shortly.
The first thing we need to do is create what is called a cache manifest file which has references to all the resources we want to save. Whether it be JavaScript, CSS, images or html, below we can view the manifest file used in the demo.
CACHE MANIFEST # Offline cache v1 # html files article.html # css files assets/_styles.css # js files assets/_javascript.js # images assets/ico_ninja-star.gif
The manifest file is a simple plain text file that holds the file names you wish to cache, the paths are relevant to where you saved the manifest file which is recommended to be in the root of the site. This file will be saved as filename.appcache, where filename is anything you wish. Lines that start with a # are comments and are ignored by the cache.
Referencing the cache file
We now have our cache manifest file setup and named, the next thing we need to do is reference that file in the html so this offline access will function for the specified files in the manifest.
<html manifest="thecssninja.appcache">
The manifest file is referenced in the html tag through the manifest attribute and just points to the filename.
Now the one issue that catches a lot of people when trying this out is not setting up the mime type correctly in their chosen web server. Whether it be IIS, Apache or something else, you’ll need to make sure that the .appcache file is fed through as text/cache-manifest.
For Apache you can add the text/cache-manifest to the mime.types file found in the conf folder in apache and add the following to the bottom of the file.
# html 5 application cache - offline access text/cache-manifest appcache
For IIS open up the IIS manager found in Control Panel > Administrative Tools > Internet Information Services double click the Mime Types icon in the manager and scroll down the list until you find the .appcache file and edit the mime type to have text/cache-manifest.

That’s it, to get a basic offline webapp to work is incredibly simple all it takes is the manifest file to specify which files to cache, declare it in on the <html> tag using the manifest attribute and you have yourself a site still accessible even if the user has no network connection.
UPDATE: GeoNomad in the comments suggested a great tool to make sure your manifest file is being fed through with the correct mime type, Web Sniffer. I put my manifest file through the Web Sniffer tool, you can see that the Content-Type is set as text/cache-manifest.
Updating the cache
If you want to update the cache you either need to change/add file references to the manifest and then tell the cache to update. Updating a file that the manifest calls will not make the cache reflect the changes. The mozilla developer article on applicationCache makes a good suggestion to version your manifest file as the JavaScript events described below will only fire if there is a change to the manifest file. To update the cache we have:
window.applicationCache;
This object has various stages depending on what the cache is doing which can be checked by using the .status method. There are 6 different stages:
- Status 0 (UNCACHED) is returned which means that there is no cache available
- Status 1 (IDLE) is returned means the cache you have is currently the most up-to-date
- Status 2 (CHECKING) is returned means there is a change in your manifest file and it is checking it for changes
- Status 3 (DOWNLOADING) is retuned means changes have been found and they are being added to your cache
- Status 4 (UPDATEREADY) is retuned means your new cache is ready to be updated and override your current cache
- Status 5 (OBSOLETE) is returned means your cache is no longer valid meaning it has been removed
These available statuses can be attached to the applicationCache object with event listeners so we can tell the web app what to do on what status. In our case we want to update the cache to reflect changes we have done.
var webappCache = window.applicationCache; function updateCache() { webappCache.swapCache(); } webappCache.addEventListener("updateready", updateCache, false);
In the above example we attach an event listener to the applicationCache looking for the updateready status which means there is a change to the manifest file and our cache is ready to be updated we do so by using the swapCache() method.
There is 2 more event handlers which do not appear in the window.applicationCache.status these are part of the event summary. Those are error & progress. We’ll take a look at how to use the error event, the progress event is basically the same as the downloading event handler.
var webappCache = window.applicationCache; function errorCache() { alert("Cache failed to update"); } webappCache.addEventListener("error", errorCache, false);
All the error event handler does is return the specified function we attached in the event listener when the cache is not available or does not exist.
Event summary
In the applicationCache we have various events available so when the cache is being updated, or as mentioned above when something goes wrong. We can attach to those events and keep the user informed on what is happening. These events will execute in specific order based on what is happening with the cache and therefore give us useful hooks to represent that back to the user.
Pete who commented below and needed a way of indicating to the user that the cache was downloading prompted me to look further into the events that get fired and which ones would be useful in this scenario. I created a demo which will indicate to the user that the cache is downloading by showing a loading icon and once the cache had finished downloading, the loader would be hidden.
The event order for this example was as follows:
- checking – The page loads and the cache is checked for any changes.
- progress – The download event actually gets fired before this but we don’t need to hook into that. The progress event will fire for each file that is referenced in your manifest until the cache has finished downloading.
- cached – The cache has successfully downloaded and the cached event is fired so we utilise that to hide the loader.
- updateready – This event is fired so we can then swap the old cache with the newly downloaded one.
In the above mentioned demo we also attached event listeners to the error and noupdate events so we can handle errors and if the cache is already up-to-date.
Is the user online
There is also a new method on the navigator object called onLine which returns a boolean value if there is a network connection or not.
navigator.onLine
In the article example the onLine method is used to update the title if the user is on/offline.
Only the beginning
The applicationCache is not yet finalised and is of course subject to change with newer and refined features. I’m sure there will be additions in the upcoming iPhone OS 3.0 release. If there are updates unfortunately these cannot be discussed until the NDA is lifted. But of course this won’t stop us speculating.
Some of the features available in applicationCache on firefox 3.1 and safari 4 will inevitably be added in future releases of the iPhone OS. Such as the NETWORK: and FALLBACK: sections in the manifest file, these allow for the developer to specify a file they wish to never cache or to have a file load if something fails with the first option.
Short sharp facts about the appcache: http://appcachefacts.info/
Post filed under: css, javascript, xhtml.
Comments
Trackbacks
-
[...] research into offline capabilities. HTML 5 offers some exciting new capabilities in this area. Here’s a great article on how to take advantage of offline access to content in HTML [...]
-
[...] und lässt sich sowohl dynamisch als auch von Hand erstellen. Richtig gute Anleitungen zum Thema gibt es bei thecssninja und auf [...]
-
[...] This article has gotten me started. [...]
-
[...] How to create offline webapps on the iPhone [...]
-
[...] How to create offline webapps on the iPhone [...]
-
[...] How to Create offline Webapps on the iPhone [...]
-
[...] Things might fail if the Cache Manifest MIME type is wrong, so use your browser's debugging tools or a service like Web Sniffer to check it (thanks CSS Ninja). [...]
-
[...] How to Create offline Webapps on the iPhone [...]
-
[...] How to create offline webapps on the iPhone [...]
-
[...] How to create offline webapps on the iPhone [...]
-
[...] How to create offline webapps on the iPhone [...]
-
[...] 如何在 iPhone 上创建离线应用程序 [...]
-
[...] 如何在 iPhone 上创建离线应用程序 [...]
-
[...] 如何在 iPhone 上创建离线应用程序 [...]
-
[...] 如何在 iPhone 上创建离线应用程序 [...]
-
[...] 如何在 iPhone 上创建离线应用程序 [...]
-
[...] found a link http://www.thecssninja.com/javascript/how-to-create-offline-webapps-on-the-iphone. According to their advice, I tried using Web Sniffer to determine if the manifest is served [...]
-
[...] Nochmal gute Übersicht und viele Tipps und viele Kommentare: http://www.thecssninja.com/javascript/how-to-create-offline-webapps-on-the-iphone [...]
-
[...] 如何在 iPhone 上创建离线应用程序 [...]
-
[...] 如何在 iPhone 上创建离线应用程序 [...]
-
[...] How to Create offline Webapps on the iPhone [...]
-
[...] How to create offline webapps on the iPhone [...]
-
[...] http://www.thecssninja.com/javascript/how-to-create-offline-webapps-on-the-iphone http://html5demos.com/storage http://diveintohtml5.org/storage.html ← .htaccess Tricks for Better WordPress SEO & Security [...]
-
[...] 如何在 iPhone 上创建离线应用程序 [...]
-
[...] 如何在 iPhone 上创建离线应用程序 [...]
-
[...] How to create offline webapps on the iPhone [...]
-
[...] How to Create offline Webapps on the iPhone [...]
-
[...] 如何在 iPhone 上创建离线应用程序 [...]
Very interesting … but is there a limit as to what can be cached? Just tried based on your model, total site is 5 mb size with hundreds of small files (4 – 15 kb). It just will not cache, while your sample on the same server performs well.
cheers
pete, June 17th, 2009No I haven’t come across a size limit nor have I found any references anywhere to indicate that there would be a size limit. One thing that did stop my web app from caching was misspelling file name in the manifest, have you made sure your manifest hasn’t got any spelling mistakes? A good way to debug any issues is to attach an event listener to the error event and see if it’s failing the cache, you can also check the status of the applicationCache and see what it’s returning. Take a look at the JavaScript file I’m using for the example it has a switch statement in their and logs useful messages to the browser console to see what the status is.
The Css Ninja, June 18th, 2009Hi, I learned last night that the current cache limit for webapps is supposed to be 5mb. I reduced some stuff, so that took care of one thing.
My true problem seems to be, when I go into a hierarchy. All links straight off the index.html page work perfectly well, but when I do the following, safari on the iPhone (not on the mac) crashes gloriously:
FILE: my.manifest
Content:
CASH MANIFEST
this.css
that.js
Vegetables/AtoZ.html
Vegetables/Spinach.html
Vegetables/Chickpeas.html
FILE: index.html
Links to:
Vegetables/AtoZ.html
Vegetables/Spinach.html
Vegetables/Chickpeas.html
Offline all three links work fine, however:
When I tap on Vegetables/AtoZ.html and from within there want to get to the Spinach or Chickpea file Safari iPhone crashes.
It is as if there was an undocumented “it only works on the the first hierarchy level”.
Have you tried a second or third level hierarchy with manifest yet? Be interested to hear from down under.
Cheers
pete, June 19th, 2009Just quoting your email so the comments make sense.
So your saying you are just referencing all the files directly and not listing their folders names before and that caches all of them? Can you provide a link to a test version that crashes the browser and one that works?
You could in theory attach to the downloading event handler for the cache webappCache.addEventListener(“downloading”, promptUser, false); which would call a prompt to ask a user if they would like to cache the site. Then depending on their answer either continue or throw an exception.
The Css Ninja, June 19th, 2009I have a question on the applicationCache status, having copied your js sample:
Changing a file and changing the manifest I get Status 2 (checking) in an alert box which I place at the top:
Afterwards the newly modified file is being displayed.
At which point can I get in with an alert box to actually confirm that the cache has indeed been updated?
I tried the following, but none of the desired alert boxes trigger:
BTW: The hierarchical problem seems to be solved. Somebody else looked into it and it might have been, because the manifest contained files which did not exist anymore. Preciser analysis in a few days.
pete, June 23rd, 2009That will always return false, what you need to do is attach an event listener to the status itself. Status code 2 will always return first if there is a change to the manifest, followed by downloading and updateready. Just do the following:
This will fire the updateCache() function and alert you that the cache has been updated.
Yep same issue I had when doing the demo, although I misspelt my file names therefore it was looking for files that didn’t exist.
The Css Ninja, June 24th, 2009Okay.
You Ninja. Me not even a half boiled rice corn.
Will this give me the right message upon update?
Lol, we’ve all got to start somewhere.
Your code looks fine only change I would make is removing the if statement in your updateCache method as that only gets fired when the updateready status is passed to listener which is already status 4 so no need to check for it again. Your onload event listener doesn’t need to be there if your not calling anything after load.
The Css Ninja, June 25th, 2009tks a lot. and now an off-topic one: the app works fine when i run it on my local server and pick it up with the iphone as part of the local network. the moment i upload the whole thing to the external providers place no caching happens. i am told it was “bad formatting” of the manifest file and that the provider reformatted it, but nothing changes the non-workability of caching on the distant server. what could be the right debug procedure? .. email me privately, if you wish.
pete, June 27th, 2009Have you set up the .manifest extension to be fed through as text/cache-manifest in your mime types on the server your uploading to? If it’s working on your local there should be no problem with your manifest file.
The Css Ninja, June 27th, 2009on the external one the declaration is in an htaccess file.
pete, June 27th, 2009I did have trouble setting the mime type through my htaccess file on my hosting, I ended up setting the mime type through my admin control panel. Just do a check for the applicationCache status to see what it’s returning on your server, if you get 0 it would most likely mean the mime type isn’t setup correctly on the server.
The Css Ninja, June 27th, 2009problem sorted. cause: reference in an html file to a css class which was no longer defined …. would you like a little js-contract? need a progress indicator during download so people know it is happening and do not interrupt too early (as downloads are approx. 4mb).
pete, July 5th, 2009If you need to indicate that something is happening I would show an animated gif icon and display it when the cache is downloading, then use the updateready event to hide once the download is done e.g.
This won’t give you exact progress, but it will indicate to the user that something is happening and if you position a container over the top of the site with the animated gif this will stop the user from doing anything until it’s loaded.
The Css Ninja, July 5th, 2009I implemented this and it works amazingly well, in Safari. But what I really want is for it to work with UIWebView, and it doesn’t seem to be doing that – does anyone have any idea on putting the two together? Any success stories?
Gavril, July 10th, 2009Just got a brand new 3GS and trying to get some off-line webapps going. I’ve been having some trouble with mine not working offline and just tried yours with the same results.
Mark, July 12th, 2009I notice through using a proxy that the phone is never requesting the “manifest” file. Seems like a bug in the phone?
What versions have you had this working on?
@Gavril – I dont see why it wouldn’t work in a native app as it would essentially be calling an instance if safari in your app. I’d be interested to know if you find the solution.
@Mark – That’s strange I have the 3GS also and it’s working fine. Try enabling the debug bar in safari, the demo logs messages to the console it should let you know if something has gone wrong.
The Css Ninja, July 12th, 2009So I try to get the anim.gif to run by doing this:
After that one I have this:
The log file gives me the protocol “Downloading” but does not show the page i create to show the anim.gif
and also I get this javascript error message:
an error for line “webappcache.swapCache()” -> INVALID_STATE_ERR: DOM Exception 11
Bit stuck now. Still half-boiled rice corn. ;-)
pete, July 14th, 2009Why are you trying to open a new window? I put together a quick demo that simulates lots of content being cached. It will show a loading icon when the downloading status is passed to the applicationCache when the cache has finished downloading and the updateready status is returned the loading icon will be hidden. I delayed the hiding of the loading icon for 2 seconds using a setTimeout, for your implementation I would just do the hiding in the updateCache function.
The Css Ninja, July 15th, 2009Learning, master, learning … I thought I need to open a window so I can close the thing again afterwards. Obviously that is not the case, so I’ll have to learn how to do that. — In the demo, thank you very much indeed for your time, the icon does not disappear however. It runs and runs and runs. ;-)
pete, July 15th, 2009Ok so the demo should work as expected now, thanks to your scenario I have discovered quite a few more useful bits of information. I’m going to update the article in the coming days and shed some more light on those discoveries.
The Css Ninja, July 16th, 2009Wonderful! The demo works in showing the gif.
Now where would I go and look for a mistake I made, when in the next step in the line
“webappCache.swapCache();”
I get this error message: INVALID_STATE_ERR: DOM Exception 11
pete, July 20th, 2009Can’t really say without actually looking at the site. Based on the W3C explanation of the exception.
Looks like you’re potentially trying to access webappCache object outside of it’s current scope.
The Css Ninja, July 20th, 2009Seem to have solved the EXCEPTION 11 error:
I deleted under
function updateCache() {
this:
webappCache.swapCache();
… and inserted
loader.display = “none”;
… plus an alert box to advise the user that the update has been completed.
The modified files have obviously been downloaded to the iPhone cache and the app works. No “swapCache” required. — This is good, but what exactly happened?
PS: Is the gif your copyright or public domain?
pete, July 28th, 2009Hmm the swapCache() method is what changes over the current cache with the updated cache. Removing that will never update the cache, even though it has detected a changed, downloaded it and fired the alert to inform the user that this has happened without swapCache all of that work will be for nothing. If you reload it will load the old cache as the new cache was never swapped.
The gif was generated from ajaxload.info just generate your own one there to better suit your web app design.
The Css Ninja, July 28th, 2009Well that IS the strange thing: SwapCache() is off, after the update and subsequent turning on of flight mode on the iPhone all changed files appear as changed, all other files can be called without problems. — Really strange. As if progresscache was performing an immediate caching.
pete, July 28th, 2009Ah but that’s the issue, SwapCache is only called if the user already has a cache. If there is an update SwapCache will swap the old cache with the newly downloaded one. If you try to push out an update to one of your cache files all the events will fire and it will act like it’s downloading a new cache but without the final SwapCache method in the onupdateready event it will never change over and the user will be stuck with the original.
The Css Ninja, July 29th, 2009UPDATED: Updated article to reflect some of the ideas expressed in the comments.
The Css Ninja, August 1st, 2009There still seems to be one problem somewhere along the line with “some” users.
While 4 testers have no problems updating, one tester with an up to date (3.0) iphone 3G reports that the update messages goes on and on and on. He finally escapes the scene, restarts the iPhone and everything appears to have been updated. — This is something we talked about before. It is a hangup at the swapcache point.
The javascript call now comes at the end of the html file (just before ) so the loader div is before it.
So it works almost as it should, but this one tester gives me a mystery, and as I had the same phenomenon before I just wonder what is not known about updatecache which could cause this.
As a separate note: Your in-depth insight into these new features and your helpfulness is very much appreciated on this side of the globe. Thanks.
pete, August 1st, 2009Hi, I’m probably the noob-iest one here, but I’m trying to make my soundboard web app work while offline. I haven’t gotten it to work with my 50+ images, but I’m willing to pursue it once I’m sure that it can cache mp3 files. Is MobileSafari capable of caching mp3s specified in the manifest?
Thanks for all your help, your site has been a great resource!
Harry Shamansky, August 19th, 2009I believe based on previous comments there is a size limit of 5mb, though this is unconfirmed. If your total assets are higher than that it may not cache or will return an error. You should be able to cache any file regardless of format, it will depend more on the file size than type.
You’re very welcome, thanks for reading.
The Css Ninja, August 19th, 2009That makes sense, though I’ve also heard that the user is prompted if the cache is over 5mb.
On an unrelated note, there isn’t a way to play a short sound without the full screen player opening in a web app, right? It’s not a big deal, as it opens and closes pretty quickly, but it still would be great if there were an alternative.
Harry Shamansky, August 19th, 2009I’m not sure if the iPhone prompts the user for more space, I know the desktop does.
Yeah audio and video on the iPhone will only play through the fullscreen player no way around it.
The Css Ninja, August 19th, 2009This is great stuff!
Josh, August 20th, 2009I got this working perfectly in the regular browser but have had no success getting it to work within a UIWebView. It returns Status 0 all the time within the view.
If you or anyone has had any luck please let me know! Thanks for the great write up.
Yeah a few people have mention not being able to get it working in UIWebView which is strange. Will keep you posted if I find out anything.
The Css Ninja, August 21st, 2009Hi there,
I’m trying to set this Cache thing up and I can’t seem to make it work.
I made the cache.manifest file and it’s correct.
I added the MIME type in my mime.conf file (Apache locally installed on my iMac).
I load the app from Safari on the iPhone, save it on my homescreen. But everytime I load it up, i get the spinner in the status bar RELOADING everything.
It’s not a matter of life and death right now, as I can run the “App” locally instaled on the iPhone through SSH, but it would be cool to cache everything on the phone.
Alex Buga, September 2nd, 2009Hi Alex,
Have you attached the various events to your applicationCache object to see if you are getting an error in the caching. Make sure in your cache file that there are no misspelt assets or non existent references in there otherwise it won’t cache.
The Css Ninja, September 2nd, 2009Hi Ninja,
Robert Selldorf, September 2nd, 2009do you have any news about the UIWebView not working with this method?
Hi Robert,
I did post on a thread in the Apple developer forums asking why the appCache wouldn’t work in UIWebView and it doesn’t look good. I haven’t got official word from an Apple employee, but from what people are saying it’s not supported.
The Css Ninja, September 2nd, 2009hi!
1- I have a problem with your demo, with firefox 3.5.. when I reload the page, i get ”
Content Encoding Error
The page you are trying to view cannot be shown because it uses an invalid or unsupported form of compression.
2- I just created a manifest file on my website. The firefox preference menu show “mysite” in the list of cached sites… Does it mean the mime type is set?
it’s 0bytes, though
thanks cssninja!
yvan, September 6th, 2009edit : answer for #2 – the mimetype wasnt set but I could edit .htaccess
yvan, September 7th, 2009Is that an issue with the demo I’m hosting on my site or is it the demo files you have downloaded? I’m using FF 3.5.2 and I don’t get that error, I do however get a JavaScript error because of the google analytics in the page but that doesn’t stop the page from caching.
The Css Ninja, September 7th, 2009I have had no problem creating offline apps this way, but I have a problem getting rid of them.
If I delete the icon from the screen and then access the same URL in safari, it starts to load and then crashes. (OS 2.2).
I have tried resetting the iPod but the crash persists. Clearly something remains in safari that tells it to look in the now non-existent cache.
I have tried clearing the History, but no joy.
Is there any advice on how to remove offline apps properly once you have created them?
TIA
GeoNomad, September 8th, 2009Since this thread is still current, I think it’s worth mentioning that Dashcode *3.0* (it comes with Snow Leopard when you install XCode) has an option to “make your webapp available offline”
It basically does all the caching work for you. I have yet to see whether it works for me, but I’ll find out soon.
Harry Shamansky, September 8th, 2009Just so you’re aware you don’t need to add the website to your home screen for the cache to work.
To clear your cache close the window in safari then quit the app go to Settings > Safari > Clear Cache, that should kill off the cache. Crashing seems a bit extreme it should throw an exception if the cache is invalid or non-existent. Perhaps that is a bug in 2.2?
The Css Ninja, September 8th, 2009That’s great news, I imagine it would purely create a manifest file which references all your assets.
Would be interesting to know if it attaches any listeners for you to do things like progress etc.
The Css Ninja, September 8th, 2009Well, it’s still very basic. Dashcode won’t even show you or let you edit the manifest file until after you’ve saved to disk or exported. Less room for error this way, I suppose.
Harry Shamansky, September 8th, 2009Clearing the cache did the trick. In fact I thought of it during the night and did it this morning before I came back here. Don’t know why I didn’t try that before.
I think it did throw an exception. For a brief second there was an Error Message bar, but Safari crashed before I could read it. Been too lazy to look in the crash log to see if there was anything relevant. Maybe I will later.
Yes, I had noticed that the cached version is used even if you type the URL offline, so there is benefit and danger to using the manifest without paying attention.
Thanks.
GeoNomad, September 8th, 2009If the only way to really remove an offline web application is to clear the cache, that means that all offline web apps will also be removed.
Is there really no way to remove a single app?
This seems like a serious problem. I already have several offline webapps on my iPod and expect many more.
GeoNomad, September 9th, 2009It’s still not right that the browser would crash just because there is an error.
Unfortunately clearing the cache is an all or nothing process, much like resetting the location services does it for every single app rather than individually. Seems they should really make it work like the notifications does.
Even with finer control over cache clearing it would still be at the app level and not the individual cached site level.
If the cache returns a 404 or 410 the obsolete event is fired and the browser will naturally delete the cache, that could be an alternative to going through the menu?
The Css Ninja, September 9th, 2009After a few hours of bug fixing I got mine running except for one thing. I like to cache some .mov files. I kept it all under 5 MB, but in Mobile Safari it gives me a “broken” play button. It works fine in firefox for example. I can’t find it anywhere on the web, but I think the native iPhone players do not use the files stored by Safari and look for the online files, right?
Matthijs, September 9th, 2009I’m not entirely sure what you mean? Is the cache not working on .mov files?
The Css Ninja, September 10th, 2009Just an update to everyone, I got official word from an Apple employee that the applicationCache is not supported in the UIWebView. But they did recommend another forum post that shows you how to have a website run locally using a different technique, in short put your files in the Resources folder http://retromaccast.ning.com/profiles/blogs/iphone-programming-for-apple
The Css Ninja, September 10th, 2009What I mean is the .mov file is cached by the browser (at least that is the case on a regular browser as I can play the movie while offline) but when I want to play the movie by clicking a link in the cached html files on the iPhone, the native application for video playback will open and I think it will look for the file on the original URL and not the file Safari cached.
About the “Resources” solution above. It is quite nice but the great thing about UIWebView is that you do not need to distribute an app.
Matthijs, September 10th, 2009Have you tried using a smaller filesize video, or just the video by itself? Perhaps there is a size limit, this is only speculation.
The Css Ninja, September 10th, 2009The video is just 1.4 MB, so it should not be a problem. In Firefox it is easy to see how much data is in the cache for each domain (firefox>preferences>advanced>network) and there the movie is included. I think only Safari can use the cache and not other programs (like the video player)
Matthijs, September 10th, 2009I wrote last week that your demo, here, crashed my firefox 3.5.2.
I upgraded to 3.5.3 today and it still does… Well.
It might be a bug specific to the linux version.
I’d didn’t dive into this technique yet, so before I do, I’d like to know if the caching speeds up an online web-application with the iphone (dynamic website with a lot of content fetched online)? What’s the best way to do? cache as many files as possible? the javascripts?
yvan, September 11th, 2009That’s a very good point. I’m sure it could be due to the fact that video and audio tags in iPhone Safari don’t act the same way as a desktop browser and would probably bypass the cache. Will investigate further, but good find.
The Css Ninja, September 11th, 2009Must be a bug with the linux version It seems fine on 3.5.3 in Vista & 7.
The whole point of the applicationCache is purely for offline access rather than speeding up the web app. Though it would make the initial visit to the site much snappier as you can cache all the pages before the user will get there. Caching all the static content would definitely speed up the responsiveness, but if you have a lot of assets you wish to cache it can make the first time visit very slow.
The Css Ninja, September 11th, 2009@Matthijs
My recent experience also suggests that embedded video is not possible offline… and that was the whole point of trying to make this small offline app.
I still hold a small flicker of hope… the iphone… no video… doesn’t sound right to me.
I did get the rest of it working offline after some problems… being that the manifest is aggressively cached and after fixing a small problem in it I had to rename it to make offline work at all. That was my biggest caveat.
Martin Westin, October 19th, 2009First thing I tried when I read this was downloading the demo.
It didn’t work on the iPhone, but the original demo did!!!
Is it because of my server?
The demo is on: http://projecten.maxmakes.nl/cache11/index.html
Max
MaxMakes, October 26th, 2009Looking at the console.logs it’s returning a status of uncached, if it was working it would return status checking. It’s also firing the error method so you may want to print whats happening.
Just add error to the error method and log it to the console, do this in Firefox with firebug so you can get more in-depth results.
I would start stripping back items in the manifest and see if that works.
The Css Ninja, October 26th, 2009I tried this but he now said it is an object event.
How can I get the error.
You can see the problem in the example of my previous message.
Thanks for helping me
Max
MaxMakes, October 26th, 2009http://projecten.maxmakes.nl/cache11/thecssninja.manifest
is returning content-type: text/plain so it won’t work.
You can check the headers using this handy tool: http://web-sniffer.net/
FYI, another working example is at http://benlo.com/jaipho – an offline slide show builder.
GeoNomad, October 26th, 2009@GeoNomad – Thanks for the handy tool. Will have to do an update to the article as quite a few people get stuck on setting the right mime type.
The Css Ninja, October 27th, 2009The mime type can be tricky, especially if you don’t have access to the server configuration. But a nice trick is to use a php script to generate the whole file, including the header. Safari is happy with a manifest file such as manifest.php and as the php can generate the content on the fly, life is easy.
Also, the php script can generate a random version number while debugging, so you can just forget about the whole manifest thing. Just remember to load twice every time. If you want a copy of one of my scripts, just email me.
For small webapps, this method means that content is always downloaded when online, and always works offline with the last load. No fuss, no muss.
GeoNomad, October 27th, 2009My company has been working on an issue with UIWebViews and caching and the solution was to build our own caching that reads the manifest.
On a separate issue – I am writing a web app and trying to cache an mp4 file and a pdf. The cache is under 5 megs. It seems the pdfs and the mp4s just will not cache. With pdf’s, it’ll try to go to the URL regardless of cache, and with the mp4, it tells me it can’t play the file. Anyone have a solution or see anything like this?
Mike D, December 5th, 2009Yeah the official word from Apple is that you cannot use applicationCache in UIWebViews.
The reason video/audio/pdf won’t cache is because they are loaded in external applications e.g. HTML5 videos get loaded in the media player and will always pull the source from the server. Same goes for audio and pdf.
The Css Ninja, December 5th, 2009Actually i was able to get a pdf to cache by loading it in a base64 encoded string (data:), but the results were REALLY slow. still, for those who really need it, may be a worthwhile solution – didn’t work for video though.
Mike D, December 5th, 2009You might try serializing with toDataURL and saving to LocalStorage.
GeoNomad, December 5th, 2009Hey does anyone know if its necessary to create a manifest file if you are using Dashcode 3.0 to create a web app for the iPod????
ryan, December 9th, 2009Depends if you are going to want it to work offline, without a manifest file offline will not work. Dashcode 3.0 allows you to tick a box to make a webapp function offline, all that does it creates a manifest file for you listing all your assets. I’m not sure how dashcode allows you to handle errors/events for the applicationCache if at all.
The Css Ninja, December 9th, 2009I have downloaded the sample zip file and after I add an htaccess file it works fine.. However, I can not add images to the small website? I did have everything working for quite sometime and had many images working, yet i keep getting a safari error when i turn off wi-fi on my ipod touch. Please help!
my .htaccess file just contains the text below:
AddType text/cache-manifest .manifest
I am super frustrated as I had everything working, yet now i can not get it to work anymore…..
Stephen, December 14th, 2009Hard to tell without some sort of example or link?
The Css Ninja, December 14th, 2009Here is the project I am working on right now.. But I have changed the manifest file, but even with the manifest file containing all the images it still breaks.. link is here.
http://www.stephencarr.net/ipod/nursing/nursing.html
Stephen, December 15th, 2009You’re image doesn’t exist, http://www.stephencarr.net/ipod/nursing/images/bg_full_screen.png, I get a 404. If you reference files that the cache can’t resolve the offline caching will fail.
The Css Ninja, December 15th, 2009It works NOW!!!! Thank you! You were correct, I was referencing a wrong background image. I corrected that and it still didn’t work, so I simply erased everything off the server just to be sure there weren’t any bad files floating around, and re-uploaded and now we are good to go! That was a pain!! But totally worth it, thanks again man!
Stephen, December 15th, 2009I’ve gotten the app manifest and offline caching working, many thanks for the article! I’m able to bookmark my site/app to the home screen and load it from there. But, once opened from the home screen, certain links will jump out and open in mobile safari – despite the fact that i preventDefault() on all link clicks!
I have an onclick event handler bound at the body level. Using event delegation, it catches any click on any link, looks at its href, and dynamically calls a templating function to update the page. I call preventDefault() on the event object – for *some* of my links this works, and the page is updated with my template. For the links that result in a hit against the local database before outputting the results of the template, the links are opened in mobile safari.
In desktop safari, all the links work even when i’m offline – something is happening that’s mobile safari specific.
Any thoughts on why some links would open offline, but others not? None of the link URLs in question are listed in the manifest file, but they don’t need to be since the link action is prevented
Jo, December 20th, 2009It’s hard to say without seeing exactly what you are doing.
You should check out iUI or jQTouch and see how they handle page loads. I’d imagine they would be hijacking the links like you are but there might be a quirk to get around the issues you’re having.
The Css Ninja, December 20th, 2009what do these links point to? are they all just regular http? some other protocols are not supported in the same manner in full screen mode as they are in mobile safari. Another reason might be your target (if any). Also, AJAX requests are not supported for caching
Mike D, December 20th, 2009can you please help me … am new to web apps but produced one using Dashcode 2.04 as only have leopard not snow leopard and need to now make the app available for offline use. Can someone tell me how to do this ? I can see from another blogg that Dashcode 3 does this for you . But i do not want to do the whole app again . Any offers on this? would be very grateful if anyone can help as there is not a lot of info on dashcode around. I know i need to create manifest but need simple guide after producing the files and deploying. thank you
nerissa, January 2nd, 2010I don’t use dashcode so I can’t help you there. I imagine updating your dashcode version won’t require you to do the web app again.
The Css Ninja, January 2nd, 2010hi there sorry just if you could let me know how to make a manifest from the files I have deployed from Dashcode anyway please. Is it the same process you have above. thanks
nerissa, January 3rd, 2010Thanks, worked flawlessly.
Dae, January 9th, 2010hi all,
just a question:
what’s the easyest way to let the user “switch” from “local” and “not local” (without manifest)?
(allowing to download the app “data” only on request?)
using PHP would be useful to include() or not the .manifest, but i wonder how to “persist” the state because PHP is processed on the server-side before client execution…
thank you in advance for any advice…
Joachim, January 15th, 2010cookies?
Joachim, January 15th, 2010@Joachim – cookies could be a good option you can then check with PHP if it’s local or not.
The Css Ninja, January 15th, 2010thanks! this was my initial idea… I was wondering if there are other (better?) options…
I’ll try it this way :)
have a nice day
Joachim, January 15th, 2010Joachim
Cookies and a php controlled manifest works well.
It is possible to implement a user button in the app to clear the cache which sets a cookie which causes php to return an empty manifest. Javascript can be used to force immediate reloads to complete the implementation.
It can get hairy debugging the sequence but once you have it working it seems to be reliable.
GeoNomad, January 16th, 2010I’ve got a question for Mike D.
I’ve been busy creating a very cool webapp and now I want to get it in the apple store.
Can you explain what you mean with: “build our own caching that reads the manifest”.
Thanks
Max
maxmakes, January 17th, 2010Hi Ninja and GeoNomad,
I’m developing an iPhone web app that utilizes cached data. The dialog here has been invaluable to debug various problems I’ve encountered.
I, too, have used a dynamically generated manifest file, but even though the content type is clearly “test/cache-manifest” (thanks web-sniffer.net), the status of the applicationCache is Uncached. Static manifest files work just fine.
Geonomad, did you set any other headers other than the Content-Type?
Thanks
CrazyIvan
CrazyIvan, January 19th, 2010Hi CrazyIvan, if you’re are still getting uncached status even though the mime type is correct. This usually means your are referencing an asset that doesn’t exist or you have the wrong path to one or more of your assets.
The Css Ninja, January 19th, 2010No other headers were needed.
As Css Ninja says… look for non-existent items.
When debugging, if something had gone wrong earlier, sometimes a respring of the iPhone was necessary to get cacheing to work again.
GeoNomad, January 19th, 2010No problems with the files listed in the manifest.
There was a newline before the CACHE-MANIFEST header. I was using Web-sniffer.net, but I didn’t have “Raw HTML View” selected. Without that option checked, the newline is not displayed.
I knew that CACHE-MANIFEST had to be the first line, but the way I had written the ASP created a “hidden” newline. See below:
The altered layout below corrected the issue:
Thanks,
CrazyIvan
CrazyIvan, January 20th, 2010Hi Ninja,
Your demos and this discussion have been invaluable.
I am using an iTouch 3.1. In my tests I can open both a .pdf and a MS Word .doc file in mobile Safari while on line. If I list only the .pdf in the cache manifest file, it gets cached with no errors. This is good.
If I list the .doc file in the manifest, I get an error event when loading the cache and the .doc file is not cached, even though it views OK when on-line. The manifest file is super simple and there are no typos. Here is the file:
CACHE MANIFEST
index.html
cache_debug.js
test.html
test.pdf
test.doc
Leave out ‘test.doc’ from the manifest and everything is cached without errors. Put it in and we get a cache error even though the server downloaded with 200 OK.
Here is the test with the .doc in place. Open the .doc while on line, it works, but it is not cached.
http://sky-report.com/test/cache-test/index.html
Have you heard any more on this? Does safari only cache a limited set of file types? It is strange that it fails to load the .doc into the cache.
Also, do you know how to see the specifics of the error event? I am trying to see why safari is throwing an error on the .doc.
THANKS!
Pb, January 29th, 2010That’s an interesting find, there could be an undocumented list of files that will not be cached. So far we know audio, video and now doc files don’t cache. The audio and video is due to them opening in an external player but doc I’m not sure why it wouldn’t cache. I tested the page in firefox and everything caches fine including the .doc file, this leads me to believe mobile safari may have a balcklist of files it won’t cache?
One theory could be that it won’t cache propriety formats, which would make all office documents fail when trying to cache. You could try saving the .doc as .rtf instead and see if that works?
The Css Ninja, January 30th, 2010Hi Ninja,
I have updated my test at
http://sky-report.com/test/cache-test/index.html
with an .rtf file instead of the doc. It behaves the same. I have some cache event logging so you can watch. It gets the file with 200 OK, but the DOMApplicationCache throws an error as soon as it hits a .doc, .rtf, .xls, and .ppt. Which are all files that can be opened by safari while on-line.
So here is another theory. Mobile Safari may have a plug-in structure similar to other browsers, so it will render files of different types using its plug-in. We see that with PDF, audio and video. I believe in iPhone 2.x, the PDF would not cache for offline viewing.
So this problem may not be a Safari problem in-as-much as a plug-in not being cache-aware.
I think safari can also open some apple formats, I will try those also. More theories, testing and comments are welcome.
BTW – how do I submit these questions to Apple? I have the free Dev registration but not the $99 yet. THANKS NINJA – YOU ROCK!
Pb, January 30th, 2010That sounds quite plausible that the plugins may not be cache aware for certain file types.
You can try the devforums, not sure if you need a paid account to get access. You could also file a bug.
The Css Ninja, January 30th, 2010Hey Ninja,
Since I couldn’t get this to work, I downloaded the source and uploaded it up another server. When o Reyes to so this again, it didn’t work like on your site.here is my testing link:
manifesttest.atspace.com
If you can tell me why this is so.
Thanks,
Gerome, February 3rd, 2010Gerome
@Gerome – See GeoNomads comment for a useful tool to let you know if you are sending the manfiest through as the right mime type. Running your one returns text/plain you need to setup on your server to feed all .manifest files as text/cache-manifest.
The Css Ninja, February 3rd, 2010Hi Ninja, i tried manifest to cache background image, the page is still reloaded and the page is refreshed. do you know how to fix this? thanks! (i wanted to cache the background image to avoid reloading the image when the site is online)
atom, February 14th, 2010by the way, i’ve tried ‘offline’ of the page, it works fine. Just when it is online, i see the background image is always being refreshed.
Thanks,
atom, February 14th, 2010Ray.
Someone heard about improvements to make video caching possible with HTML5?
NicoVB, February 15th, 2010@Atom – Is it actually requesting and downloading the image again? It could be reloading it from the cache and that could appear to look like it’s downloading from the server again.
The Css Ninja, February 15th, 2010WWWHHHYYYYY cant i get this to work lol,
z3r01, March 2nd, 2010ok so i suck at this but heres what i wanna do ,
i wanna use iWebKit on an app, no internet at all, just iWebKit and the app…i created a manifest file but in xcode, do i point to the manifest file or just to the index.html but make sure i have the manifest file in there?
@z3r01 – Xcode should take care of the referencing and creating of the manifest file so all you need to so is load the index.html page. If you look at the source there should be an attribute on the html tag i.e. <html manifest=”…” >
The Css Ninja, March 2nd, 2010Great stuff! The demo is working and I created my own example from your info and that’s also working.
But, none of them work for me if I close the page in Safari and re-open, then I get a no connection alert from the browser and a blank page. Is this supposed to work like that? I don’t see the point if the user is not allowed to close the page in Safari..
Btw, using a 3GS with everything up-to-date.
Hansn, March 3rd, 2010@Hansn – Hmm, I just tried it myself using my demo (I’m on an updated 3GS too), put it into airplane mode went back in to safari and reloaded the page and went to the second page without a problem. I also closed the window, opened a new one and typed in the address again and it loaded without issue all while still in airplane mode.
I did however get the connection error on the second page when clicking the “back to home” link, but I think that was because it was trying to load /index.html instead of just / and the fact that it isn’t added in the manifest. Looks like the cache gets confused when you try to link to the same file by using different names.
The Css Ninja, March 4th, 2010Cheers for the testing! What I’m trying to do is to cache a web app that’s added to the home screen. This shouldn’t be any different from opening a page in Safari (right?). But what do you get if you:
Open your demo, add it to the home screen, open safari, close the page, close safari and click the web app icon?
That’s my problem here, I always get a connection error, but maybe it has something to do with trying to open / vs /index.html as you said.
Hansn, March 4th, 2010Did a test and renamed your index.html to index1.html, created a new index.html with an onload redirect to index1.html just to have the home screen icon pointing to a file and not /. But I still get the same connection error. It feels like Safari is dumping the cache when the app is closed without having the page in it.. weird!
Hansn, March 4th, 2010@Hansn – So I followed your steps of loading it in safari, putting it on the home screen etc. All works fine for me, loads the pages without issue and all the cached assets appear.
Have you changed the demo at all, or is it the exact same as my hosted demo?
The Css Ninja, March 5th, 2010It pretty much the same but I get the same thing when I run your demo, long step by step with your demo:
1. Empty Safari cache, just to get a clean start…
2. Open Safari
3. Browse to Ninja demo, not loading the second page
4. Add to home screen
5. Open Safari
6. Close demo tab
7. Close Safari
8. Enable Airplane Mode
9. Run Ninja Demo with homescreen icon
10. Safari is opening a new tab, saying “Turn off Airplane Mode…”
11. Then saying “Cannot Open Page…”
12. Blank boring page showing :(
Something is very fishy here if you get the demo when doing this..
Hansn, March 5th, 2010I can’t re-create your problem. I followed your steps exactly and it all worked fine for me? Have you got anyone else with an iPhone to try this demo out and follow your steps?
The Css Ninja, March 8th, 2010Thanks, I’ll check with some people and post the result.
Hansn, March 8th, 2010we just had a similar problem with one of our apps. turns out a complete shutdown of the iphone and a restart did the trick. the cache is caching again properly.
pete, March 8th, 2010Do you know of any way to tell Safari to only download changed or newer files? It seems that if the manifest has changed at all, every file is re-downloaded.
dosboy, March 15th, 2010No unfortunately it’s all or nothing. There is no real way for the application Cache to tell what files have been updated or added, it works off the manifest time stamp to detect if any changes have occurred.
The Css Ninja, March 15th, 2010hmmm…. seems like if you add your webapp to homescreen, user opens it, navigate to an internal page, and then receives a call (interruption). On awake it will execute the script tags. Is there anyway of stopping it?
simon, March 24th, 2010Do you mean once you end the call and it goes back to safari, does it try reloading the page? If you’ve added it to your home screen it will have already cached the assets. Could you explain in a bit more detail what exactly is happening?
The Css Ninja, March 24th, 2010Just to help those that, as me, don’t know how to alter the conf file on a public server, the Apache has an option to do so. Just create a file .htaccess with the following content: “AddType text/cache-manifest .manifest” and place it on the same directory as the index file. This should solve any problem you may face!
Vasco, March 24th, 2010Just a quick cache manifest question. I am using php to create a dynamic page using a framework. So when I create a page it is not with an extention. So my application would be located at something like http://somedomain.com/my/mobile/app. Can I include this in the manifest and have it cache my html output of that url? I started as a static html file but have to dynamically generate the html.
Justin, April 10th, 2010Justin, if that generated page references the manifest file it’s considered whats called a master file which will automatically be cached and available for offline use. You shouldn’t have to do anything other than make sure the html tag has the manifest attribute.
The Css Ninja, April 10th, 2010hmm. for some reason it does not cache. when it was just an html file it was fine, but as soon as it is dynamically generated, it does not cache.
Justin, April 10th, 2010Have you tried just specifing the folder in the manifest? e.g. my/mobile/app/
The Css Ninja, April 10th, 2010Thanks for the help, I had some path issues. Is there a way to force the cache to refresh even if the manifest has not changed? So if they are online it refreshes everything anyway?
Justin, April 13th, 2010Justin, I haven’t tested it but you could try doing a swapCache() call on the noupdate event e.g.
Not sure if that will work or not. Otherwise you’ll have to make an update to the manifest like a comment version number in my example.
The Css Ninja, April 13th, 2010I’ve read the article that explains how to implement HTML 5 offline resource caching in web apps. I’ve tried testing this locally: added the MIME type to the list, created a Cache Manifest (as described), changed my doctype to the HTML 5 doctype, specified the manifest attribute and the correct path on the HTML element — but still I don’t see the manifest file being consumed by the Safari Browser at all.
But, my offline-caching Enabled Page refreshes successfully at IE 6.0 & Google Chrome browsers even when the LAN is disconnected.
I just don’t know how to further troubleshoot the issue and would welcome any suggestions.
Tapobrata, April 13th, 2010It’s hard to say what your issue is without seeing it. Can you provide a link?
The Css Ninja, April 14th, 2010I was trying to find a way to give the user feedback on how far the downloading of the files that are mentioned in the manifest is progressing. You mentioned in your article that the progress event will fire for each file that is referenced in the manifest until the cache has finished downloading.
So I thought here is my solution. I just put a counter in the handler function of the progress event and I know exactly where I am with my download.
Unfortunately this did not work out well. I have 38 files in my manifest and my counter goes up to 75.
Do you any idea?
Timo, May 24th, 2010Could one build the cache into the actual web page you are caching? Similar to how one can include css and javascript in the page without having to reference the file.
The reason I ask is because I am trying to build an ‘e-publication’ that I would like to be able to allow to be read offline. Rather than have to create a separate file, it would be really useful to create a manifest for the page that will eventually be downloaded and read offline.
Much easier than creating five separate files (one for css, one for js, one for images, one for the actual page and one for the manifest)
This is currently being created as a WordPress theme (you can follow the link above, which works on iphones/touches and kinda-sorta on the ipad)
If you know of a way that I could actually build a webarchive ala safari’s, or collect all relevant files in one location, that would be awesome too.
Gerry Straathof, June 10th, 2010Could one build the cache into the actual web page you are caching? Similar to how one can include css and javascript in the page without having to reference the file.
The reason I ask is because I am trying to build an ‘e-publication’ that I would like to be able to allow to be read offline. Rather than have to create a separate file, it would be really useful to create a manifest for the page that will eventually be downloaded and read offline.
Much easier than creating five separate files (one for css, one for js, one for images, one for the actual page and one for the manifest)
This is currently being created as a WordPress theme (you can follow the link above, which works on iphones/touches and kinda-sorta on the ipad)
If you know of a way that I could actually build a webarchive ala safari’s, or collect all relevant files in one location, that would be awesome too.
(repeated because I screwed up my email)
Gerry Straathof, June 10th, 2010Hi,
Just a quick question, can I access cache.db file located at ~/Library/Caches/com.apple.Safari/Cache.db through javascript.
Ketaki, June 25th, 2010Hi,
so i am new to creating web apps for iphone.
my cacheing seems to work correct but this may be off the subject.
so i am calling
to get rid of the nav bar on the top and the bottom (to make it look like a real app) when online it is working properly but offline it is not. i always get a “cannot open page for BLAH” retry or cancel this is when i add it to my homescreen button. any ideas or have you guys seen this problem. i am also using jqtouch for my simple animations.
thanx again
Robert, June 28th, 2010Let’s say i have index.html & HELLO.html in the manifest.
index.html contains a link to HELLO.html (which in fact is just a div with some text).
HELLO.html will work when i’m online but not when i’m offline, even though HELLO.html is in the manifest.
Any ideas? :)
Dennis K., June 29th, 2010> You can check the headers using this handy tool: http://web-sniffer.net
There several other free tools available as well. Live HTTP Headers firefox addon or FREE Web Tools from HTTP Debugger Team:
web developer, July 3rd, 2010http://www.httpdebugger.com/tools/
@Ketaki – In short no. Is that what dashcode names it’s manifest file? You can’t access local files in javascript on mobile safari.
The Css Ninja, July 5th, 2010@Robert – can’t say without seeing an example.
The Css Ninja, July 5th, 2010@Dennis K – That’s exactly what my demo has, an index file and a link to another page. You don’t need to visit the second page in order for the cache to save it locally, compare my demo to your files.
The Css Ninja, July 5th, 2010@Timo – The progress event should only fire for each file in the manifest, can you provide a link to the demo?
The Css Ninja, July 5th, 2010I love the way your demo includes a facility to check if the user is currently on/off line. I’m wondering; have you encountered a way of seeing if the user is online via wifi or cellular? I’d presume it’s impossible with a webapp although possible for native apps?
kheda, July 23rd, 2010@kheda – The
The Css Ninja, July 23rd, 2010navigator.onLineproperty can’t tell you what connection you have only if you have a connection. Sskype can tell when you’re on wifi or 3g so it would be possible in a native app but not through the browser.I am trying to work with SVG fonts in a project (trying not to have any bitmap scaling for logos and such)
SVG fonts in mobile safari require a font id in the url, which is indicated as a #123456789 after the svg (font-name.svg#123456789)
because the cache manifest registers the # as a comment, is there any way of ‘tricking’ it into not seeing the # in the font name?
Thanks. Thanks a whole bunch.
Gerry Straathof, August 11th, 2010@Gerry – In order to cache the svg file I don’t think you would need to have the fragment identifier in the manifest file, you only need it when you reference it in the css file. Just add it as font-name.svg and it should be cached.
The Css Ninja, August 11th, 2010SVG files aren’t working. Period.
I tried the following: I forced the site to use only the SVG fonts. I ensured the manifest was accessing only the .svg (no Font id)
In chrome, while running an audit I get the errors:
Resource interpreted as font but transferred with MIME type image/svg+xml.
In the .htaccess for the font folder I have added:
AddType image/svg+xml svg
Note: I have singe removed all references to the web fonts and cannot get it to work. In chrome, there are no errors in the audit except spcifying image dimensions, serving static content from cookieless domain and minimize cookie size. Sit is: http://straathof.acadnet.ca/beta2.4/ (webfonts turned back on right now)
Gerry Straathof, August 11th, 2010I just tried adding an svg file to my example manifest and it’s caching fine.
Go to my demo on your iPhone let the cache update and then go into offline mode and visit the svg file it will load fine in offline mode and is getting cached.
The Css Ninja, August 11th, 2010Yup. the file caches fine, but can you use it?
Here is a small sample. the larger text should appear in veggieburger bold. It will work well in safari when you open it, and if you open it from a saved homepage icon online it will work and display the font. When you open it offline, though it will not.
the @fontface reference in the stylesheet looks for a url that ends in a name associated to the font within the svg file. It is after a #. The one for veggibold is: veggibol-webfont.svgz#webfontfLhiEZTN
because this complete url is not part of the cache manifest it can’t find it. It won’t fail because it will still find the svgz file, but it will not render with the font. I need a way around tat before I can use webfonts in mobile safari, either by fooling the cache.manifest or inside the @fontface call…
Example: http://www.straathof.acadnet.ca/pinch/
Gerry Straathof, August 14th, 2010@Gerry – I double checked the spec to see if they say anything about fragment indetifiers in URLs and came across this interesting side note.
This may be a bug then if according to the spec a # in a url should be taken as a fragment indentifier and therefore work…
The Css Ninja, August 14th, 2010i am using html5..i just made a simple html5 page. here manifest is given to thehtml5. that page run correctly on dekstop…it works in work offline mode too…but when i run that same page in samsung wave mobile. then it dont cache the html page.
please tell wat can i do for this
content in manifest file as givenbelow:
CACHE MANIFEST
index.html
and in html page manifestadded as:
after this thrs only static data give
now please tell any other modification need to be done for mobile
Puneet, August 20th, 2010@Puneet – The page that calls the manifest file is automatically included in the cache you don’t need to specify it. Just having the cache and putting the attribute on the html tag will suffice. I’ve never used a Samsung Wave so wouldn’t know if it has any quirks. Try this checklist web app on your wave it uses a manifest for offline access.
The Css Ninja, August 20th, 2010Sir thanks for reply
1. can you please tell, is this necessary to place manifest attribute
on each html page or it just place on front page??
2. in manifest file smarty templates need to be added or not??
Puneet, August 20th, 20103. i cant access the sql database on mobile, do u know any working example of offline database on client-side??
as i am using smarty and php in my project, is there any need to add all templates that are in my project to specify in the manifest file??
Puneet, August 20th, 2010hello sensei , ive got some troubles over here that i think im not supossed to have ,i’ve been trying to make something to go offline but i just cant i even try the easyest example ever , something like this
index.html:
Stuff
some stuff to be offline here
————————————————————————————
style.css:
p
{
border:1px solid black;
}
—————————————————————————————
stuff.manifest:
CACHE MANIFEST
index.html
style.css
—————————————————————————————-
im running apache with the mime type already added
its supossed that the browser automatically ‘saves’ the manifest file as it reads the manifest attribute on the HTML tag right?
after it loads , i turn the server off and the page just wont load after reloading and i dont know what im doing wrong , please some help over herre newbie in troubles
Gustavo, August 23rd, 2010@Puneet – You only need to place the manifest attribute on the initial page then inside the manifest you list all the assets you wish to cache.
The Css Ninja, August 23rd, 2010@Gustavo – Grab my demo and try that on your server. If that’s working you’re doing something wrong with yours. If it’s not make sure the mimetype is set, double check it with the web sniffer tool mentioned in the article. Lastly make sure you’re testing it on a browser that actually supports the application cache.
The Css Ninja, August 23rd, 2010hi well i tried with your demo on my server and it runs smoothly , im using chrome 5 ,so i guess the trouble its me xD , but how can somebody make any mistake with a example like the one i posted :S!!
so i guees ill keep on trying to find out what am i doing wrong thx!!
Gustavo, August 23rd, 2010ok now its working i dont know what was the problem i just moved the css file to a folder and change the url in the manifest file and voila , but now i have a question , i added some lines to index.html more specifically i added elements but they just dont render at first i tought it was because the server was down but it wasnt so i dont know whats happening! :S
Gustavo, August 23rd, 2010@Gustavo – Most likely it was a bad reference to that css file, if there are any 404 on files you list in your manifest it will fail.
Make sure you clear your cache and you’re using the appcache event model to detect changes in the manifest so you can swap the old with the new, otherwise it will load the originally cached assets and you won’t see any changes.
The Css Ninja, August 25th, 2010i am making web application that works offline. I used database system in my application. i successfully save data on client side during offline. now i don’t know how to synchronize client side data storage with the server?
Puneet, September 3rd, 2010as gmail runs in the iphone. we can do all work during offline but when internet connection comes it synchronize with the server.
i want same thing in my application i don’t know how to send request back to server after internet connection comes.
please reply
@Puneet – Onload of the web app you can check navigator.onLine status and if it’s true sync your local databse with your server.
If they drop connection while using your web app and then regain it you have two events that get fired on the document called “online” and “offline”. Capture these events and delegate what to do when they lose or gain a connection.
The Css Ninja, September 4th, 2010thankx sir
Puneet, September 7th, 2010i got it
Thanks for sharing such a nice sharing..
sahibinden, September 11th, 2010hey i’m having problems with an app i’m making, and wondered if you might be able to help… i’m trying to make a browser based app that just displays my website. this works fine but when i click a linkto an external site, i have no way of going back as there is no back button. is there any way to make certain links open up the safari app, so my app just navigates pages that i have made? i’d appreciate any help you can give – this is really frustrating!
nightleaf, September 23rd, 2010@nightleaf – If you save a website to your home screen and it has the meta tag to make it full screen any external links should automatically open the safari app. Are you loading any javascript that may be hijacking these link clicks?
The Css Ninja, September 23rd, 2010hey, i’m not saving the website to the homescreen, instead i’m making a standalone app that is simply a browser window that links to my website. the idea being that i would submit it to the app store and upon download it would navigate around my website within the app, but upon clicking a link to an external site it would open safari.. i just wondered if there was anything i can do to make this happen?
nightleaf, September 23rd, 2010@nightleaf – Ah right just did a quick search and found a solution to loading links in safari from a UIWebview. Looks like that’s what you need.
The Css Ninja, September 24th, 2010ah that’s fantastic, thanks very much
nightleaf, September 24th, 2010I’m just working on my first iPhone offline app and came across your site. I’ve just tried your demo in offline mode (airplane mode on), and the site tells me it’s online still and it complains about not having internet access.
I’ve tried adding it to my home screen and this fares no better.
Am I doing something wrong?
Thanks
John
John Polling, October 1st, 2010Thank you CSS Ninja. I’ve learnt a lot from your tutorial, comments and participants.
I’m newbie in the whole matter; webapps as well as javascript.
I want to know if there is a way to force the iphone to add your webapp to the home screen automatically without tapping (+).
regards,
Ahmed, October 2nd, 2010@John P – It’s hard to say, what iOS version are you running? Have you tried other offline examples? I just tried it myself on iOS 4 and it’s working fine.
The Css Ninja, October 4th, 2010@Ahmed – Unfortunately you cannot force it to save to the home screen, you have to go through the devices predefined steps to get it there.
The Css Ninja, October 4th, 2010I am finding it impossible to get my app to work in offline mode. When I put my iPhone 4 running iOS 4.1 into airplane mode, I just keep getting an error that it “could not be opened because it is not connected to the Internet.”
webApp
I’ve read through all the comments here and many other sites and have been unable to find a solution. I did use the Web-Sniffer and my manifest seems to be the correct mime type.
I’m at a loss and hope that someone here might have a solution.
Steve V, November 4th, 2010@Steve V – Looking at this in Firefox the cache is zero so something isn’t caching. The application cache will not work if any of your references return a 404 or some other error code. Having a quick look at your manifest you point to two assets, rightOn.jpg and rightOff.jpg, that are getting a 404 which causes the cache to fail. If you remove them from the manifest it should work fine.
The Css Ninja, November 4th, 2010Thanks! You’re awesome! That did the trick. Figures it would have to be something “simple” like that.
Steve V, November 6th, 2010Hi CSS Ninja! I developed an iPhone web app that works alright when my iPhone 3G (iOS 4.1) is online, but when I’m going offline (Airplane mode) I get an error “Cannot Open App: App could not opened because it could not connect to the server.” My manifest (offline.manifest) file contains all of my files and I’ve set mime-types on my (local) server (Apache). I checked it using Web-Sniffer.net and the result is “Content-Type: text/cache-manifest”. I cleared the cache, rebooted my device and then I tried to open the web app at “http://MyIP/folder/index.html” (not just “http://MyIP/folder/”), but I got the same error. Also, I removed all of my “window.location” and “location.replace” JavaScript code, because I read that other users had problems with JavaScript redirections. I’m desperate… I just want to run offline a web app (HTML, CSS, JavaScript and images). Can someone please help me?
Note: I don’t know if this is important, but my CSS code has WebKit animations.
Dinos, November 7th, 2010@Dinos – If you’ve verified that everything being done correctly, then strip back your manifest references to eliminate the chance that your are referencing an assets that doesn’t exist. Quickest way to resolve issues is to strip it back to the raw functionality.
The Css Ninja, November 7th, 2010I have found this php snippet which is supposed to go through all the files in the directory and include them in a manifest cache…
isFile() &&
$file != “./manifest.php” &&
substr($file->getFileName(), 0, 1) !=”.”)
{
echo $file .”\n”;
$hashes .= md5_file($file);
}
}
echo “# Hash: ” . md5($hashes) . “\n”;
?>
You call it with this code:
I have been trying to use it, but since my webapp is too large (over 5M due to images) but it may work for others…
Gerry Straathof, November 7th, 2010Well, that trick didn’t work… sorry. not sure if you can find it, but you can find some of the missing code if you meander through this site:
http://straathof.acadnet.ca/beta6.6/iphone/
http://straathof.acadnet.ca/beta6.6/iphone/manifest.php
Gerry Straathof, November 7th, 2010Hello,
I tried this demo on iPad but it is not working. It is working on my laptop.
Do I have to set anything on my iPad that this (and other offline pages) will work?
best S
Sobis, November 7th, 2010Is there a way to make a progress bar (using css/javascript) that indicates the percent of the cache that has downloaded?
Charles Thompson, November 8th, 2010I just tried it on my iPad and it worked fine.
The Css Ninja, November 8th, 2010@Charles T – The applicationCache does have a progress event that will fire for each file in your manifest as they are being downloaded. I did do a demo that uses the progress event.
The Css Ninja, November 8th, 2010Hello, I was trying to get my app working on my ipad and it does seem as if there is a limit on the file size. Currently my app is in total 16mb and I couldn’t figure out what was keeping it from working without using the java. Is there any way to get a website to work locally offline on the ipad other than a web app? Or is there a way that I could get this to work without reducing the file size? Thanks!
Zack, November 13th, 2010@Zack – There is a 5mb limit for cached items using the applicationCache for the iPhone. I’m pretty sure it’s the same for the iPad.
How else would you store a website offline? You don’t need to save a website to your home screen to store assets in the users cache it’ll work in the safari app just fine.
The Css Ninja, November 16th, 2010hi
Alan, November 16th, 2010First of all I can’t help but congrat you for the quality of your code writing. It’s become sufficiently rare to be worth noting :)
2ndly I’ve been playing for a while with caching on the ipad, and I wanted to confirm that it works using UIWebViews with iOS 4.2
And lastly I get an error at the end of your demo firing the errorCache function. And I’m not sure I understand your (function() {})(); syntax forvthe js code. Any hint ? Thx !
Just for clarity sake…: I tested it on the iPad Safari with debug console on, which gave me the errorCache message.
Alan, November 16th, 2010@Alan – Thankyou!
Interesting, can anyone else confirm applicationCache works with iOS4.2 in a UIWebView? Thanks for the heads up Alan.
The Css Ninja, November 16th, 2010(function(){})()that syntax creates a closure in javascript so as not to pollute the global scope. Basically you can have private variables.Ok for the private scope trick. Neat…
But still have the errorCache problem: the logged messages I got when I launch your demo in iPad’s Safari are (in this order):
- “Cache status: Uncached” (applicationCache.status == 0)
- “Downloading cache…” (progressCache)
- …
- “Downloading cache…” (progressCache)
- “You’re either offline or bla bla bla” (errorCache)
and btw I get the same problem using UIWebView app (iOS 4.2).
Alan, November 17th, 2010It seems that updateready never occurs and I get an error state instead.
Other than that, as I said, the site pages remain visible in my UIWebView app even when in Airplane mode (but that didn’t work prior to iOS4.2, at least for the iPad).
I had issues with debug in safari affecting my scripts. If you have it on expect problems and I would suggest not leaving it on all the time.
Also be careful about clearing cache indescrimnately during testing. I have found it clears the cache for all bookmarked files. Since I have stopped clearing it my tests have been much more durable (although it is around 50m cached total right now)
I would rather Apple saved the bookmarked site as a web archive, bypassing the hassle of caching for offline stuff.
Gerry straathof, November 17th, 2010@Alan – I’ve tried this demo in my iPad and the error event isn’t firing. Will investigate further and see if I can reproduce it.
The Css Ninja, November 17th, 2010When my webapp is “online”, why can I not pull new content through AJAX? It tries to locate everything in the CACHE, but it isn’t in the CACHE so it just gives me an error. Is there some secret to loading new data that I don’t know about, can it even be done (without having to completely download a new cache)?
Charles Thompson, November 17th, 2010ok. thx for trying to reproduce. the only diff between your setup and mine could be the os version (4.2 8c5115c on my side).
Alan, November 17th, 2010this is the link i used: http://www.thecssninja.com/demo/offline_webapp/loader/
Thx again for sharing your great experience
A.
Hi,
Firstly, I must say this link is immensely helpful!! Thanks a lot guys,keep up the good work!
Secondly, I have a very basic question (Im new to this whole thing)
@Ninja: you mentioned “If you save a website to your home screen and it has the meta tag to make it full screen any external links should automatically open the safari app.”
Does this mean that if I have a added “m.abcd.edu/index.html” app to my home screen and i have a link to “http://pqrs.html” it will open up a new safari window, even if i have it cached in the manifest?
So can i only add ” m.abcd.edu/anotherfile.html” (i.e: a file somewhat relative to my current path ) if I dont want to open a new safari window. I basucally want the capability to seamlessly redirect to a new page (even if its on a completely different path) as long as i have it cached.
Thanks!
PS
PS, November 18th, 2010@Charles T – Are you caching the file you’re calling to in your XMLHttpRequest? In your cache manifest you can specify files that must always be called from the network.
The Css Ninja, November 18th, 2010@PS – You can get around that issue by loading in your pages using XMLHttpRequest. I’m sure one of the many webkit frameworks already handle this.
The Css Ninja, November 18th, 2010@Ninja :
So this is what I want to do. Please! let me know if thats what you are referring to when you say XMLHttpRequest
I want to store “site.edu/index.html” on my home screen.
This index.html is going to contain 4 separate widget files : site.edu/eat.html ,
hotel.html,
fitness.html,
movie.html
My index.html’s manifest is going to contain all resources : the 4 htmls and their own resources like images,js etc..
Now, what I want to do is! :
1) Open the saved “index.html” from my homescreen (when im in airplane mode)
(So this will basically open it using UIWebview and not my actual safari browser , i assume)
–And NOT have it jump to my safari browser when I click on eat.html
So basically I want a BIG app that has 4 SMALL app widgets in it..which shouldn’t have to load in new safari windows. (But since each is a completely different app, I do need 4 html files, I cant just use divs..)
I hope I didn’t lose you’ll midway :P
Thanks!!
Do let me know if you’ll hav any suggestions
PS, November 19th, 2010So, if I have to put every URL in the “white list”… then what happens when I load a page through XMLHttpRequest that has images on it? Do those images have to be on the “white list” as well?
Charles Thompson, November 21st, 2010@Charles T – If you’re doing XHR calls to load extra data and you want to cache that page and it’s assets. You’re probably going beyond what the applicationCache was designed for.
The Css Ninja, November 22nd, 2010@Ninja
Basically, I have a webapp that has cached files so the layout loads faster. I want to be able to load external content inside a div using XHR, whether it be text, images, or movies. I am able to achieve loading text just fine, but I cannot load images through XHR because they are not listed in the cache manifest file.
Charles Thompson, November 22nd, 2010@Charles T – Well loading images or movies through XHR will return the file in binary format which is pretty useless, you can’t just insert a blob of binary data into a document and expect it to render the image/movie.
If you can get the relative URL to the asset create a new video/img element and set it’s source to the url and insert it into the document.
The Css Ninja, November 22nd, 2010Hey Master Ninja,
Alan, November 22nd, 2010Any update on the errorCache problem by any chance ?
I hate to get this error not knowing why, while I am just using the demo on your very web site. Are you using the 4.2 beta iOS on the iPad ?
Please advise. Thanks !
@Ninja,
My XHR loads data from a PHP document on my server. The data from the PHP document is render as HTML. I have tags in the data that comes from the XHR call that reference images on my server. My issue is that the I cant seem to load images that are not listed in the cache manifest, which is really silly.
Charles Thompson, November 22nd, 2010@Alan – I’m not running iOS4.2 on the iPad so won’t be able to test.
The Css Ninja, November 22nd, 2010@Charles T – Hmm that is weird, hard to say without seeing a demo. Do you have any test code that reproduces your problem that I could look at?
The Css Ninja, November 22nd, 2010You can see what I am working on here, it’s very much in beta still…
iota42.com/tixczar
Charles Thompson, November 22nd, 2010Well after many trials which more or less “screwed up” Safari’s cache I used the good ol’ method that works 9 out of 10 times…:
Alan, November 23rd, 2010I power cycled my iPad and it now works like a charm….
I get coherent cache messages and no more error message…
mmmmhh… I’m not very enthusiastic as I still dont understand what happened. If something goes wrong again i’ll let you know.
Thanks anyways…
@Charles T – Looks like iOS4.2 got released today will update my iPad when I have a chance and have a look.
The Css Ninja, November 23rd, 2010I can confirm that on the iphone3G there is a 5MB cache limit. It wouldn’t cache the files until I got it all down to under 5MB (no other changes). You can simply remove a bunch of images from the manifest until caching works. On the iphone4 the limit is higher, but I have no idea what it is. I think 12MB worked fine.
Jacob Mouka, November 27th, 2010Hi,
my Webapp is still not working if I am offline.
I’m using an iPod Touch 2g with iOS4.2, the cached Files are under 5mb, and the content type is text/cache-manifest!
I’ve also included the manifest in the Tag!
Any ideas why it doesn’t work? :)
Flo, November 29th, 2010@Flo – Strip your manifest file back to bare essentials, there’s a 90% chance you’re referencing something in there that either doesn’t exist or has the wrong path.
The Css Ninja, November 29th, 2010Thanks so much for the information on the post
Madhusudhan, December 2nd, 2010Ninja, do I understand these comments correctly:
Ajax requests can not be cached via the manifest file?
I use jquerymobile, which uses Ajax to retrieve the different pages/screens in the app. In the standalone version with manifest file the cache does not return pages (html) through Ajax.
Humble greetings,
Hans, December 2nd, 2010Hans
@Hans – No applicationCache cannot store ajax requests. I think jQuery Mobile can also use hidden containers with ids as “pages” rather than loading in html from another page.
The Css Ninja, December 3rd, 2010This is so interesting. It makes me want to improve my study habits while taking these Java, JavaScript classes and getting ready to use HTML 5. I wish you lived next door and I could pay you to teach these classes! Awesome website for explaining How to create offline webapps on the iPhone!
Carla, December 6th, 2010Great article!! Any thoughts on doing this with audio/streaming? I’m guessing that we are in the same world, just dealing with different mime-types.
Jonathan Coe, January 27th, 2011@Jonathan C
The Css Ninja, January 27th, 2011Same deal with video as it uses the external player to load and play audio, caching the audio wouldn’t work offline.
Thanks for the great guide. If I could offer some advice to anyone who is having trouble getting this to work, it would be to make sure that you clear the cache on Safari iPhone after making changes. I was having trouble getting the app to load offline and troubleshooted for several hours to no avail. Finally, I decided to try loading the app offline on OSX with Safari and Firefox and it worked perfectly. That clued me in that it was the iPhone that was the problem. I ended up clearing the cache, cookies, and history on the iPhone and then restarted the phone. Afterward, the app worked perfectly. Thanks again for the guide, it helped a lot.
Kush, January 29th, 2011That’s a good idea. I have taken to renaming the folder I am drawing my site from. For instance, it’s named “beta10″. I make some changes and change it to beta10.1 and so on. I don’t have the cache turned on until after I have all my alterations made to the web site, however. I learned from experience that not all changes recache properly.
Gerry Straathof, January 30th, 2011I’ve used your code – awesome BTW! However I have a question that is slightly OT.
I am trying to use localStorage for my offline app that I create using a different page in the online site. That is, I want to download data for the offline app using a different page while online. However, none of the data shows up in the the offline version, but I can see it if I go to the url of the page online.
Any ideas/suggestions?
Thx.
snelldl, March 17th, 2011@snelldl –
So If I get this right you’re caching a page that stores data using localStorage. But when you’re offline you can’t access that localStorage data until you go to the page that executes the code to do so? Do you have a demo or something to show whats happening?
The Css Ninja, March 21st, 2011I got it figured out. Not sure what I was doing wrong.
However, I do have a different question.
On the iPhone, when I add my app to the home screen, changes I make to localStorage when I use it don’t get picked up by the online version unless I go in and out of airplane mode at least once. I’ve seen other people with the same problem in various forums.
Any ideas?
BTW, I didn’t get your reply in my email.
snelldl, March 23rd, 2011@snelldl -
That’s a weird issue would be worth putting a test case together, could be a bug with iOS safari.
The Css Ninja, April 6th, 2011Dear Ninja, thanks for the how to!
However I’m having issues with my webapp caching. Thanks to your JS I could discover that the log says “Uncached”, and for some reason my webapp isn’t caching. I’ve double checked everything, even stripping the manifest to the bare essentials, and it still doesn’t seem to work. Any idea why? Thanks.
Here’s the demo:
leo prieto, April 7th, 2011http://iphone.spoon.cl/ilupa/
@leo prieto –
Seems it’s an issue with your server. I slurped your site down and tried it locally and it caches for offline access just fine.
The Css Ninja, April 7th, 2011Hi.
At first i have to say you got a great blog and its very useful for everyone. congrats.
I am facing a big problem using Sencha. there is a lot of JS and CSS. I have put all files in cache.manifest file but still not working. I dont what i can do anymore.
Have you seen any problem using Sencha Touch?
Thanks in advance.
Filipe Menossi, April 14th, 2011@Filipe Menossi –
Take a look at their tutorial on the very subject.
The Css Ninja, April 14th, 2011Hello,
I’m having a very strange issue with the mime type setup. I downloaded your example and tested it on my webspace…it works offline…great!
I’m also having a dedicated webserver. So I started to test the offline feature there. It was not working. I checked the mime.type and the manifest decleration was missing.
So I added the the line text/cache-manifest manifest to my mime.types file and restarted apache. I double checked with web-sniffer and the output mimetype was correct. However the webapp was still not displaying offline. I ran another test and typed in the URL to the manifest file into my firefox:
- On my webspace (offline is working) firefox wants me to download the manifest file; The same behavior occurrs when I type in the URL to your manifest file
- On my webserver (offline not working) firefox just display plain text.
On both systems web sniffer tells me that the content-type is text/cache-manifest
What am I doing wrong? Do I have to setup anything else in my apach configuration?
Thanks in advance
mojorisin, April 15th, 2011Thanks the tutorial, very helpful – though I am having a problem with my app. I can get it to store offline but the Javascript fails to work?
Any ideas?
jonathan bennett, April 19th, 2011@mojorisin -
Make sure know assets referenced in the manifest are 404′ing if that happens the whole manifest is thrown out.
The Css Ninja, April 21st, 2011I ahd dveloped a html page with offline capability uisng the manifest ,it is working fine with firefox but not working on the safari .
ragini, April 28th, 2011ur app is gr8 but i have a que about web offline. if my html generate dynamic means it not a .html or php file even its a servlet call, where as parameter pass the name of app and server read app name xml files and generated html content and return browers, how can we make these kind of sites webapps offline work? any idea?
Neha, May 3rd, 2011Thank you for putting together a great introductory piece. This was very useful in getting me up and going and I referenced this in my blog post at http://mattsnerdwerd.blogspot.com/2011/05/ios-and-application-cache.html.
Matt Ray, May 6th, 2011Hi, thanks for your tutorial, I have a question, how can create a dynamic manifest file, with ASP code, because in my online application the user can active and desactive mode offline and I can’t to erase cached files. I tried with two distinct files, but both files are cached and don’t delete files.
Ej:
First Manifest
CACHE MANIFEST
styles.css
image1.jpg
file.html
Second Manifest
CACHE MANIFEST
Network
*
Also I tried with ASP code in manifest.asp
styles.css
image1.jpg
file.html
But this manifest don’t working.
Thanks for your help
Fernando, May 15th, 2011I’m having a hard time adding the Custom Mime type on my server. My website is hosted on Godaddy, IIS 7, Windows.
There are no Mime Types on the Control Panel. I try creating the MIME with web.config file at the root folder, and all I got was to shut down all my website with an internal message error. I try creating a .htaccess file too but no success… any idea how could I try to fix this???
Thomas, May 25th, 2011@Fernando –
It’s very hard to say without seeing a some sort of testcase to get an idea of what you’re trying to do.
Ryan Seddon, May 27th, 2011@Thomas –
If you can access the IIS manager on your server it’s an easy change. IIS doesn’t use .htaccess so if you want to add a mimetype you can do it through the web.config if the IIS manager is not accessible.
<mimeMap fileExtension=".manifest" mimeType="text/cache-manifest" />A key note.
I found that iOS (iPhone, notably) appears to not support Apache Last-Modified / If-Modified-Since headers.
So, for an application cache to work it’s critical that you’re using access based cache expiration headers instead of modification based cache headers.
Would be curious if you’ve seen the same behavior!
Thanks,
Sam
codeviking, June 1st, 2011@codeviking –
I have not come across that behaviour! Do you have a testcase showing the issue? I would like to update the article and point to an example of it happening.
Ryan Seddon, June 8th, 2011Nice article, Good job.
Thanks to guide.
Cheers!
Incircle Media, June 15th, 2011Very good tutorial. Great job.
Nithin, July 7th, 2011WebKit browsers won’t cache it.
For some reason, Chrome and MobileSafari won’t cache my site.
So I double checked that the mime-type on it was right and it was.
Firefox does it fine. When I checked the Chrome Console it said:
Application Cache Error event: Invalid manifest mime type (text/plain) http://i.finalscalc.co.cc/cache.manifest
I’ve put it through the web sniffer and it identifies it as text/cache-manifest.
The cache file is below.
I can’t figure out what’s wrong. Thanks for your help, PitaJ
]CACHE MANIFEST
PitaJ, July 19th, 2011]
]CACHE:
]# Offline cache v1.0
]# html files
]index.html
]about/index.html
]
]# css files
]css/developer-style.css
]
]# js files
]javascript/functions.js
]finalsCalc.js
]
]# images
]images/arrow.png
]images/tributton.png
@PitaJ -
Looks like you’re missing the CACHE: bit just after CACHE MANIFEST.
Ryan Seddon, August 3rd, 2011I made a iPhone4 webpage using html5, canvas, audio, javaScript and others. It works well. For a while it wroks off line. But soon it disappears. So I would learn your instructions here to make my site stand alone.
Iori Fujita, August 13th, 2011The page itself is a page for Schoenbrg and Kandinsky.
http://www.geocities.jp/imyfujita/air/air.html
Made the manifest file and added the html code. Loaded it on safari, saved bookmark to home screen so I can run it as a web app, turned on airplane mode, then loaded the bookmark and I get a popup saying: “…could not be opened because it is not connected to the Internet.”
But it loads fine after I hit “Retry”. Am I not added enough files in the manifest? Anyway of getting rid of this window that pops up? I want it to run just like an app when offline. Thanks.
lmwong, August 22nd, 2011@lmwong –
Hard to say without seeing exactly what you’re doing.
Ryan Seddon, August 22nd, 2011It could be that 45 of the resources don’t have expiration dates. I usually leave a two year expiration date for the items on my sites. lib2obf_b8.js has a short life as well (once it runs out, it will have to reload)
I found this using the audit in safari’s developer menu.
Gerry Straathof, August 22nd, 2011I have found the cache initialization is not ‘instant’ on the advices, and usually takes 30 seconds or more before the device realizes that “oh. you want to SAVE this stuff… pfft… here. Baby. there. satisfied?”
I certainly wish they had just used a web archive system like on the desktop version of safari. So much less complicated.
Gerry Straathof, August 22nd, 2011Great article, helped a good deal. I have an issue with the status always returning 0. Using several tools to verify my cache.manifest, it returns the correct mime type and has no syntax errors. Trying to troubleshoot the process and there really aren’t a lot of places to set breakpoints. I’m using IIS 7 and the site has the mime type of mime type set correctly to text/cache-manifest. Am I missing something here? I’ve tested the manifest on the latest versions of chrome, safari, and firefox with no success except for being able to determine the 0 zero status.
Jeremiah, October 13th, 2011@Jeremiah –
The applicationCache API is very fragile and will break at any given chance it gets. Your error seems like you either have a misspelt asset in your manifest or one that doesn’t exist. Do you have an online version to look at?
Ryan Seddon, October 16th, 2011Thanks!
Anders, November 2nd, 2011Any idea how to be able to use more than 5MB for?
Is it per page, per site or per “app” the limit is set?
Cheers!
I don’t know what i’m doing wrong!
I made the mobile site and used the almost the same code of the DEMO.
Please, take a look and tell me why images aren’t going to the iphone cache.
The mobile:
http://www.rincaogrill.com.br/beta/iphone/
TNX
Rodrigo Aranha, November 8th, 2011@Rodrigo A –
Your manifest file has the wrong mimetype web-sniffer is telling me it’s application/octet-stream.
Ryan Seddon, November 8th, 2011I am having lots of problems with this, so if you don’t mind I would like to ask you a few questions. I have checked everything, but my real scenario is complicated, so I have tried to upload your project and it is not working for me:
http://www.portfoliomultimedia.es/apps/offline_webapp
http://www.portfoliomultimedia.es/apps/offline_webapp/thecssninja.manifest
The only thing I have changed is the .manifest, because it is the myme termination I added.
So, my questions would be:
- Is there something more to check in the server than the myme type?
- All the files loaded by the initial index must be in the manifest?
- If I have a video added to the manifest it fails or it just doesn’t cache it?
- Are you all sure about the 5mb limit?. I have been trying and think that I have seen a dialog asking me to let the app grow the mb limit.
- Is there any issue related to the app being in fullscreen mode?
Thank you very much for this great tutorial
Jorge
Jorge, December 21st, 2011@Jorge –
Your hosted demo is missing a reference to the vomzom.svg file, if any file is missing that’s declared in the manifest it will fail.
No, just the files you wish to cache so they’re available offline.
I believe iOS5 may allow videos and audio to be cached offline, before that it didn’t work.
I’m not a 100% sure this is what other people have found to be the case, there may very well be a prompt to increase storage size.
Fullscreen mode should be fine, if it’s a UIWebView inside an app offline caching is not available.
Ryan Seddon, December 22nd, 2011The message that comes up when you visit a cached site is to increase the cache storage of your device, not the individual site. I’ve had.mine go up to 50M when doing beta testing. if you installed the Kindle reader you will also get a confirmation.
The individual site allowance is above 5M on ios5, but i am not sure how much more. the highest mine has gone is 9.75M for a website magazine that was part of a class project.
I use a php file which builds a manifest file for a site using everything in the folder. it has made it much easier to control changing documents.
I think the kindle reader and new York times(?) use sql to hold their downloaded data, but have notdirected their codes behaviour with chrome or safari audits…
Gerry Straathof, December 22nd, 2011Hi Mr Ninja
Jmv, December 30th, 2011Thanks a lot for all your great work and help!
I ve installed a launch screen to your demo app on my iPad (ios4.2.1)
I have the very same problem as many people above: works fine online/offline but if I 1/ go offline 2/suppress the screen in safari , then I get the message ” cannot acess bla bla bla… ” when i restart the webapp, which makes it not very usefull…
Unless I missed a line, I think you answer has always been up to now: ” i don’t have this problem with my IOS version”. Is it still the case or have you experienced the problem and found a solution? what ios version do you use?
Thank in advance for you enlightments.
Hi Mr Ninja
Jmv, December 31st, 2011(previous post continued)
I have done a lot of tests with your files on my website (jmv38.comze.com). Thanks to your console-data-logger I have found the following strange facts, please comment if this sounds correct to you:
- your code makes an offline app from the file ”index.html”, but on the ipad/safari I can access to the offline page only by calling ”jmv38.comze.com”, and not ”jmv38.comze.com/index.html” that returns an ”no connection” error.
- then the call back to ”index.html” from ”article.html” never works offline. Putting href=”jmv38.comze.com” doesnt work either because it seems to call ”jmv38.comze.com/index.html”…
So I thought I was now ready to make of my own page (a game timer) a webapp. I have done everything as in your code (and copied your console-data-logger with minor modifications), and… ‘:-(( it doesn’t work! The cache apparently downloads the files, but at the end of the process an error is fired. If I put 1 or 2 html files only in the cache the errors fires much faster. I have used the sniffer to verify that my manifest has the correct mime-type: ok. So I have no idea of what is happening… Could you give a look to the problem? Your help would be very very very much appreciated! Thanks in advance!
Jmv
This totally kicked ass! Thanks for the great article.
I just wanted to share that the article.html page links back to
http://www.thecssninja.com/demo/offline_webapp/index.html
instead of just http://www.thecssninja.com/demo/offline_webapp/
which causes a “Cannot Open Page” error; no doubt because it thinks that “index.html” is different to “/”. Changing the url back to
http://www.thecssninja.com/demo/offline_webapp/
fixes the problem. you might want to correct this in the link itself :)
thanks again!
Brett, January 4th, 2012Hi Mr Ninja, it’s me again.
I have done some more tests I’d like to share with you.
I have put your code in a new domain name, and everything worked very fine online, offline, all the console message were OK.
Then I have added a single line in the 2 html files:
This is to make the app open like a stand-alone app, not in SAFARI.
Jmv, January 5th, 2012And then everything went wrong: always an error fired after downloading of the cache.
So I suppressed the line, changed the cache revision so it updates the files, but it never worked back again… My safari seems to be stuck in a ”problem state” from where it won’t go out. Don’t know what to do…
Any advice?
Best regards.
@Jmv –
I just tested your web app in firefox, chrome and iOS5 safari, they all work offline and the caching works correctly. I can’t see any problems with your code of manifest file (although your manifest file should now have the extension .appcache over .manifest, but that shouldn’t effect anything).
Ryan Seddon, January 5th, 2012@Brett -
Thank you! I’ve updated the demo and demo files to add “index.html” to the manifest file so now that link back to “index.html” will work offline correctly.
Ryan Seddon, January 5th, 2012Thanks for the post. Very helpful. When I read about the Mime type I thought “That’s why it’s not working!” but alas things are still quirky.
Using an iPad2:
1. I visite your demo page online
2. I then go offline and visit the demo page again by entering http://www.thecss... in the navigation bar. I select the demo page from the drop down and the demo webapp comes up fine.
3. Hit refresh; Safari come up with message. Cannot Open Page: Safari cannot open the page because it is not connected to the internet.
4. If I enter the whole address in the bar and click ‘Go’ I get the same error message.
5. If I make a bookmark and click it offline I will get your webpage without the error message.
My application on the otherhand will only continue to work after being disconnected if I do not navigate away from the page. I can’t bring the page back up with out getting the error message when I have disconnected from the network.
Is there a setting that will instruct safari to look for a cached website before it tries to connect to the internet? That seems to be the issue.
Thanks, Doug
Doug, January 10th, 2012@Ryan Seddon
(previous post continued)
Hi Mr Ninja
Thank you very much for having looked to my problem.
So for you everything was ok and for me there was an error.
I have tried again my own webbapp after not trying for one week and..
It worked! No error, everything fine! Even as a stand-alone webbapp (with a launch screen and not opening in Safari). Why is it so unpredictable?
I have found an excellent site that give some explaination of what might be happening here. In short: it has to do with the fact that files send by the web server to safari have themselves some ”lifetime” and are not resend systematically, even if they have changed. Another ”cache” is involved here, the native browser cache, that is different from the ”appCache” we are trying to put in place. So although we change our file on the server side, it may not be changed on the iPad-Safari side, at least for some time, depending on how the lifetime is parametered on the server side! The site gives some advice on how to put some more commands on the .htaccess file to makes sure files are resent each time they are requested on the client side. I haved tried these commands, and also forced the safari cache to empty, but since everything was fine it has not changed anything.
This excellent site is: http://diveintohtml5.info/offline.html , see the chapter named: THE FINE ART OF DEBUGGING, A.K.A. “KILL ME! KILL ME NOW!”
The file refresh problem I just described might well be the cause of the problems many other users have experienced, driving them nuts! So I hope this post will help them.
So now i should be happy with my webapp… but not quite. I have implemented some sound effects in an .mp3 file: they work fine online but not offline. Do you have any idea of what might be going on? Maybe caching mp3 is not allowed on ios 4.3? I have found no clear answer on the web.
Any help on the subject would be highly appreciated
Thanks
Jmv, January 15th, 2012JMV