I’ve been mucking with AppCache, aka ApplicationCache. It’s the secret sauce that lets you build offline apps, which is great for performance and fabulous for pretending to be an iPhone app when you’re not.
Quickstart an Offline App
As with most HTML5 technologies, the basic usage is quite simple:
- Create a trivial trio of HTML, CSS, and JS files, maybe with an image or two. (Or reuse an existing toy app.)
- Link to a "cache manifest" file from your HTML file's html tag like so: [html] [/html] </li>
- Make the manifest file. It's just the literal phrase "CACHE MANIFEST" on the top line (I know, bit random), followed by the list of files in your app:
CACHE MANIFEST clock.html clock.css clock.js clock.png
- Mark it as MIME type text/cache-manifest. If you're SSHing to a virtual host (like I did with Dreamhost), all you need here is a one-line .htaccess file:
AddType text/cache-manifest manifest
</strong>
</ol>
That's it. Now those files above will be cached locally and won't need to be downloaded again next time. To test it, load the site, shut down your net connection, and reload. It's still there innit.
It works the same on your app-phone - on iPhone or Android (or others maybe), load the site, switch to airport mode, go back to the browser and reload ... the site's still there. Where it gets really fun is making it into a regular app:
- On iPhone, bookmark the site with the Safari "+" button, choose "Add to Home Screen", and the app will be sitting alongside all your other apps on the home screen.
- On Android, bookmark the app in the browser. Hold your finger down somewhere empty on the home screen, choose add "Shortcuts" | "Bookmark", and choose the bookmark you've made.
- Online resources that can be cached (CACHED). As shown in the example above, it's the stuff that's available for caching.
- "Fallback" resources in case a file isn't cached (FALLBACK). These are like catch-all email addresses; any resource that's not cached, is a candidate for a fallback. There's a pattern-matching algorithm to map resources (which mightn't have been cached) to other resources (which hopefully have been cached). For example, you probably wouldn't cache every wikipedia article, so the fallback section would ensure a special "offline.html" page is shown for those missing articles.
- Online-only resources (NETWORK) Resources which should never be cached, e.g. it would be a good idea not to cache stock prices if people were making million-dollar decisions on the back of what they see on your possibly-cached web application.
Practical Tips and Troubleshooting
Purging the Cache
In practical terms, you are quickly going to come up the no. 1 problem of developing against a cache. How do you purge it whenever you update your code? Simple. You only need to make an arbitrary change to the cache manifest file, so just include a version number in the comment:CACHE MANIFEST # v1 clock.html clock.css clock.js clock.pngKeep revving it up every time you change any file, because changing those files alone won't have any effect. And if it's getting serious, you'll want to practice the principles of DRY and continuous integration by automating this process.
Ridding yourself of Errors
An unfortunate thing happens when there's a downloading error: The whole thing silently fails. Until debugging tools get better, if you find your app's not updating, you ought to check each of the resources specified in the manifest really, really, carefully.Cached Resources
Cache manifests are not exempt from standard caching rules, so the manifest itself, as well as other files might be cached. Pain. A good solution is to use the following Apache directives to .htaccess:ExpiresActive On ExpiresDefault
That MIME Type
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).The Wording
The wording can also trip you up. Be really sure it's exactly "CACHE MANIFEST" at the start of the file. Again, better debugging tools in the future will help here.The Fancy Stuff
All of the above is enough to get up and running with an offline app, and maintaining it too. But wait, there's complexity too!Fine Control Over What Gets Cached
The cache manifest file actually allows three kinds of resources:CACHE MANIFEST # a comment # v37 # (version number unnecessary # but recommended for cache purposes) # the following "CACHE:" is optional; # a special case because top of file # is cache by default # CACHE: images/sound-icon.png images/background.png # note that each file has to be put on its own line FALLBACK: / /sorry-i-am-offline.html NETWORK: /stocks/*