Take your webapp offline

Network Problems
Network Problems (Jeremiah Roth)

In a previous project, we needed information from farmers about what crops they had on their land. As a digital-first service, this was all done via a web UI. Having taken the app out to user testing, we found that this rich internet application struggled with low bandwidth connections. Even after we minimising and compressed the javascript, CSS and data, it wasn’t enough. So we ended up with a new requirement – how can we take our webapp offline?

As we delved deeper into it, we discovered there were two use cases.

  1. Farmers without broadband links need to download their data from eg a library, update at home and then return to the library and upload the changes
  2. Agricultural Agents would download the farm data onto their laptops, take their laptop to the farm, make changes and then upload the changes upon return to the office.

For the former, we needed some portable document which people would understand so we looked at using Microsoft Excel. We’d create it using Apache POI when they asked to download the data. We’d use the same software to process the uploads. I won’t discuss this further in this post.

For the latter, we looked at using the Web Storage mechanism in modern browsers. This was part of the HTML5 standard but has been split out. It’s supported by the major modern browsers, and will let you store 5mb or more within the user’s browser (by default – the values may change if the user has changed their configuration).

The easy-start mechanism (snippets use Angular hence the $scope bits):-

// Store the data offline
localStorage.setItem("storedParcels", JSON.stringify($scope.parcels));
 
// Retrieve the data from localstorage whilst offline
$scope.parcels = JSON.parse(localStorage.getItem("storedParcels"));
 
// Delete the locally-stored data (once you've gone back online)
localStorage.removeItem("storedParcels")

// Retrieve the data from localstorage whilst offline
$scope.parcels = JSON.parse(localStorage.getItem("storedParcels"));

// Delete the locally-stored data (once you’ve gone back online)
localStorage.removeItem("storedParcels")

Alongside this, you’ll probably also want an HTML 5 cache manifest to specify which files can be taken offline.

CACHE MANIFEST
# 1442223841678
CACHE:
/assets/app.js
/assets/angular.min.js
/assets/index.html
/assets/main.css
/assets/maincontroller.js
NETWORK:
*

The number in the second line is the application startup time – this means that this file will change each time the application restarts (so browsers can detect the manifest has changed).

You’ll also need to think about some form of locking or collision detection on upload to cope with any changes that have happened whilst you’ve taken the data offline.

Source code for this is available at https://bitbucket.org/AndrewGorton/webstorage – follow the readme on the Develop branch.

Footnote: Remember that if you’re storing data on user’s computers, you may need to comply with PECR.

This is my personal blog - all views are my own.

Tagged with: , , , ,