Yesss! Just got the localStorage and cached application to work offline for the first time!

Now, to do that with real data, and extend beyond the listAll function.

Offline App Development

… is a pain.

Mainly because once you add a file to the manifest, and thus to the browser’s app cache, you’re never sure if it’s getting updated. I spent most of last night and much of today just trying to get the browser to fetch the new version of html doc, and then the correct js file. Too bugged. It seems to be an issue primarily with Chrome & Chromium, but they are my primary development platform.

Anyway, if despite all the changes to manifest, restarting servers, clearing browser cache, the browser is still fetching old cached files, here’s a way out:

  1. Open a new tab in chrome/chromium and go to ‘chrome://appcache-internals/
  2. Clear all cached app resources
  3. Refresh the page to confirm there are no more cached app resources
  4. Refresh your test page – it should fetch everything from the server now

There’s another bit I learnt and implemented (though my implementation is pretty simplistic): Dynamic Cache Manifest.

Basically, instead of writing the application manifest, for offline app storage, by hand and changing it every time you change a file, let your server-side script do the work. What I’ve done is :

  1. Hand-wrote a cache manifest file but with a comment line that includes a django tag {{ts}}.
  2. Changed my app.yaml so that instead of serving the file directly, the request for it is sent to my server script.
  3. In the script I use the handwritten cache manifest and replace the ts tag with a random number.

What this ensures is that the browser is forced to fetch all elements in the app manifest every time because of the random number changing cache manifest on every fetch. This ensures that while I’m connected to the server and testing my js scripts, I get the latest versions every time. On the other hand, when I switch off the server and test the offline mode, the script still has resources available offline for rendering.

There is a lot more you can do here with the dynamic cache manifest rather than just plug-in a random number. I learnt this trick from this blog at Cube, and there are a couple more handy tricks being used there, so I suggest reading that resource.

Update: Seems like, as with script-initiated xhr requests, Chrome also makes multiple requests for the cache manifest from the server for every page load. When I use a randomizer function to send a ‘new’ cache manifest every time, this results in the two cache manifests being different to each other and thus Chrome doesn’t save any files. Not what I wanted, now? So, here’s a small change I made

previous randomizer: int(random.random()*10000)
new randomizer: time.strftime(‘%y%m%d%H%M’)

Now, instead of returning a new resource every time, I return a new resource every minute. This means that the two simultaneous requests that Chrome fires, will get the same cache manifest. But a page refresh/load later, will return a new cache manifest. It’s working so far :)
[Ofcourse, I know that there’s still a remote chance that the two requests will hit either side of the minute change. But the probability is small enough for me to take a chance.]

Another code restructuring /

Yesterday I restructured (I think they call it refactoring) all the code to integrate it into a single html template and a single python class. Also moved all calls to POST so nothing is visible, and editable, from the URL.

Today, I realise I may have to restructure (refactor) the application again. Yesterday’s restructuring was to bring in simplicity and order. This time it is required for the ‘offline webapp’ bit. This is what happens when you use the learn as you go (cross the bridge when we get to it) approach.

Looks like I’ve got another few long hours of boring, error-prone, code restructuring ahead of me :/