Offline version of a web app

DEMO

One of the path breaking features of HTML5 is the ability to run an html application in an offline mode.  This becomes a very handy feature particularly on hand held devices like an IPAD, Tablet or a cellphone. IPAD and Iphone browsers already support HTML5 offline caching.

The offline mode that one talks of effectively caches the site on the browser. It is not something which was designed to run the entire html app as an offline application. But with a bit of innovation, one can make an HTML5 app run in offline mode to simulate a native app. Add to this, the advantage that this HTML app is OS independent thus saving the headache of developing different apps for different Operating Systems.

Click here to view our offline brochure which gives details of our clients. The entire functionality works online on any browser and offline on an HTML5 browser.

When we attempted to develop an app, we encountered a lot of practical issues for which there was very little documentation available. Without some of these features, the offline mode becomes more a theoretical concept offering no real value to the user. There are still some issues which we have yet to get round but we believe that the list below provides a starting point to develop a good offline app.

Cache limit

HTML5 allows download of files via the manifest file. This is pretty well documented and works file. The problem arises when the size of files starts going beyond 5 MB. In most cases, your total size of all cached files will be far higher than this limit. In fact, Safari on IPAD would just give you an error with no other help. Safari on IPAD has a cache limit of 5 MB by default. The idea is to stream files via the manifest file in such a way that it prompts the user to allow increase of the cache limit. This is how we achieved it.

var cache = window.applicationCache;
function addInstallationMessage(){
	...
}
cache.addEventListener("cached", function () {

	addInstallationMessage("Please click on reload to continue the offline version download.",2);

	sendDownLoadMsg = false;

}, false);

cache.addEventListener("checking", function () {

	 addInstallationMessage("Files checked.");

	 sendDownLoadMsg = false;

}, false);

cache.addEventListener("downloading", function () {

	addInstallationMessage("Files are downloading.");

	sendDownLoadMsg = false;

}, false);

cache.addEventListener("error", function (e) {

	addInstallationMessage("The download failed for some reason. Script is attempting to download again.",2);

	cache.update();

}, false);

cache.addEventListener("noupdate", function () {

	addInstallationMessage("Installation complete",1);

	location.href="home.html";
}, false);

cache.addEventListener("progress", function () {

	if(!sendDownLoadMsg){

		addInstallationMessage("Cache download complete.");

		sendDownLoadMsg = true;

	}

}, false);

cache.addEventListener("updateready", function () {

	cachInt = 0;

	addInstallationMessage("Files checked.");

	cache.update();

}, false);

Basically, the  Application Cache Object – window.applicationCache has different states and each of those is sensed by adding event listener function. Hence, the status codes help us to track the cache download progress in HTML5 browsers.

Database download

Now that we have managed to get our files cached, the next item on the agenda is to get your database data offline. Again, in reality, a good app would want the database data besides the files. The way we got round this is to insert the relevant tables from MYSQL to SQLite. This is executed through a series of SQL statements. The javascript call for any event then checks if the browser is in online or offline mode. HTML5 allows this via navigator.onLine variable. However, we have used the jQuery ajax functions to work around with offline and online mode. jQuery allow us to define the success and error mode functions of ajax.  If the browser is online, the script will connect to the live MYSQL database via an Ajax call. If the browser is offline, the script will query the local SQLite database. By and large this works well for not so complicated applications. There are still a few challenges which we are still working on. Some of them are:
- No proper progress bar when data is being downloaded from MYSQL to SQLite.
- Reversing syncing from SQLite to MYSQL.
- If you delete browser cache conciously unconciously, your SQLite data gets wiped out.

Progress bar

We haven’t found any resource on the net which offers a solution for a proper progress bar when the files are being cached. If data of 50 MB is being downloaded, one cannot just show the user a blank white screen. We have managed to get some kind of activity being shown on screen during the course of download, but it is still not a full fledged progress bar which shows the percentage completed etc. But we believe that there is a workaround for this which we hope to come up with soon.

HTML5 does open up opportunities for offline apps but some innovative solutions are required to get it functional like an full fledged native app.

Leave a comment

4 Comments.

  1. Thank the author very much for this astonishing content. Great work!

  2. Wonderful article. This was a great help to summarise thoughts.

  3. Hi,

    This is the only article I found about overcoming the 5mb cache limit on iOS, so thanks very much for the hope you’re giving me! :razz:

    However, I can’t seem to implement it… :sad: caching always stops at 5mb .

    Is the content of the function addInstallationMessage() important or can it be just an alert(“…”)?

    I copied your code in my html file but nothing happens.. Would it be possible for you to provide an example file?

    Thanks!

    • Hi Paul,

      We checked and it seemed to work fine for us. Will try to see if we can get you an example file.

      Regards

      sapnagroup

Leave a Reply

Your email address will not be published. Required fields are marked *

*


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>