@agup
esri.github.io/offline-editor-js/demo/
Loss of connection is common in mobile apps!!
Allow users to keep working, seamlessly
Avoid application crashes or errors
Gracefully fail or degrade
Slow or intermittent cellular internet
Slow or intermittent WiFi
Avoid HTTP Timeouts
You don't have to be remote!
Can lose internet at any time.
Data
HTTP requests
HTML/CSS/JS/images
&
Most common.
Offline for a short period of time
Does not require browser restart
Fail gracefully, graceful degradation
Online
Offline
Online
HTTP Request
HTTP Request
Offline for an extended time
Expect full functionality
Requires offline browser restart
Online
Offline
Online
Restart
Browser
Native JavaScript
localStorage
IndexedDB
Application Cache
Service Workers
3rd party storage libraries
Simple to use
Limited to 5 MBs
Store only Strings
Persistent between browser restarts
// Window.localStorage
// Set an item -- Must be a String
localStorage.pageNumber = "2";
// Get an item
var pageNumber = localStorage.pageNumber;
// Remove an item
localStorage.removeItem("pageNumber");
More complex than localStorage
50 - 100MB + (on mobile devices)
Stores Objects, Strings and more
var transaction = db.transaction(["myObjectStore"], "readwrite");
transaction.oncomplete = function (event) {
dbOnCompleteHandler(event);
};
transaction.onerror = function (event) {
alert("There was a problem writing to the database");
};
var objectStore = transaction.objectStore("myObjectStore");
// Write object to database
objectStore.put(object);
A.K.A. Cache Manifest, AppCache
Stores .html, .js, .css and images
Files available online and offline
Temperamental
Use with localStorage/IndexedDB!
Browser automatically recognizes the local copy
<html manifest="example.appcache">
...
</html>
CACHE MANIFEST
# Time: Thu Mar 26 2015 09:45:14 GMT-0600 (MDT)
# Home Page
http://www.example.com/index.html
http://www.example.com/main.js
http://www.example.com/css/main.css
http://www.example.com/images/header.png
/example.appcache
Typical console log...
Very limited support (Chrome)
Requires HTTPS
Acts as a network proxy
More complex than AppCache
PouchDB, localForage
They wrap localStorage, IndexedDB and/or WebSQL
Require an addt'l library
Offer addt'l features
Offline.js (3 kb)
Set HTTP.timeout
Capture HTTP request failure
Caveats:
- 404's and connection issues
- Use Hybrid detection when available
function validateOnline(callback) {
var req = new XMLHttpRequest();
req.timeout = 15000; //ms
req.open("GET", "http://someurl.com/test.png?" +
(Math.floor(Math.random() * 1000000000)), true);
req.onload = function() {
if( req.status === 200 && req.responseText !== "") {
req = null;
callback(true);
}
else {
req = null;
callback(false);
}
};
req.ontimeout = function() { callback( false ); };
req.onerror = function() { callback(false); };
req.send(null);
}
function buttonClickHandler() {
Offline.check();
// Fail gracefully if offline
if(Offline.state === "down") {
alert("Sorry, app is currently offline");
}
else {
// Do something
}
}
function submitFormClickHandler() {
Offline.check();
var newAddress = street + "," + city + "," + zip;
// Store changes locally
if(Offline.state === "down") {
localStorage.newAddress = localStorage.newAddress +
"|@|" + newAddress;
}
else {
sendDataToServer( newAddress );
}
}
Offline.on("up", function() {
sendDataToServer( localStorage.newAddress, function() {
localStorage.newAddress = null;
});
});
Very difficult to determine why HTTP requests fail.
PhoneGap/Cordova, Titanium, etc
Use the same JS coding patterns!
Cordova check network status:
cordova-plugin-network-information
function checkConnection() {
var networkState = navigator.connection.type;
var states = {};
states[Connection.UNKNOWN] = 'Unknown connection';
states[Connection.ETHERNET] = 'Ethernet connection';
states[Connection.WIFI] = 'WiFi connection';
states[Connection.CELL_2G] = 'Cell 2G connection';
states[Connection.CELL_3G] = 'Cell 3G connection';
states[Connection.CELL_4G] = 'Cell 4G connection';
states[Connection.CELL] = 'Cell generic connection';
states[Connection.NONE] = 'No network connection';
return states[networkState];
}
var internetStatus = checkConnection();
Browser crash or device restart = okay
User clears browser cache = not good
Full device reset = not good
Always:
Listen for offline conditions
Protect all HTTP requests
Set HTTP timeout
Cache resources when feasible
Use as little memory as possible!
Upload 14MB zip
Add 1.5MBs to IndexedDB
___________________
Cached 196MB
===============
Andy Gup
agup@esri.com @agup
andygup.net