It’s easy enough to include Google Maps in a Sencha Touch application but it gets a little bit more difficult when we need to handle the offline state.
When a user does not have an available Internet connection or the user decides to shut off network connectivity on their device (i.e. activating flight mode) then all functions in the application should still work, or they should fail gracefully.
In the case of Google Maps, we obviously need an Internet connection for it to function. If we don’t have a connection though, we certainly don’t want our app to fail due to errors thrown by the library not being loaded. We also want to let our users know that they need to connect to the Internet if they wish to use the maps feature, not just display a blank screen.
What cases do we need to handle?
Ideally, we want the following things to happen:
- If there is an Internet connection available, load Google Maps
- If there is not a connection available, do not load Google Maps and display a message to the user
- If there is initially no Internet connection, and then an Internet connection becomes available, load Google Maps and remove the error message.
- If there was an Internet connection available and then it becomes unavailable, disable Google Maps and display an error message.
This problem gave me quite a lot of grief until I came across a blog post by Rohde Fischer: Sencha Touch 2 – The maps connectivity issue. I won’t rewrite the tutorial here, Rhode does an excellent job at walking through the code and you should definitely check out his blog. The solution is specifically for Sencha Touch, but the concepts could be easily applied in other circumstances. Although there is quite a lot of code, the key part is the connectivity listeners:
addConnectivityListeners: function()
{
var me = this;
var onOnline = function()
{
console.log('online');
if (typeof google == "undefined" || typeof google.maps == "undefined") {
me.loadGoogleMaps(me);
} else {
if (!this.online) {
me.showMap();
this.online = true;
}
me.enableMap();
}
};
var onOffline = function()
{
console.log('offline');
me.disableMap();
};
document.addEventListener("online", onOnline, false);
document.addEventListener("offline", onOffline, false);
},
This allows us to listen for changes in the network connectivity and trigger whatever functions are necessary for our app to continue functioning correctly.
Just one small change…
Rhode’s fix worked almost right out of the box for me, but there was one little change required. If I were to initially be offline, then switch to being online, Google Maps would fail to load. After using [my debugging program][3] I found that it was still complaining that no connection was available (even though the function is only triggered once a connection is available).
It turned out that it just needed a couple of seconds to connect, so I added a Delayed Task to the onOnline function to solve this problem:
var onOnline = function () {
//Wait for connection
var task = Ext.create('Ext.util.DelayedTask', function () {
if (typeof google == 'undefined' || typeof google.maps == 'undefined') {
me.loadGoogleMaps(me);
} else {
if (!me.online) {
me.showMap();
me.online = true;
}
me.enableMap();
}
});
task.delay(2000);
};
This causes the function to wait 2 seconds before executing, which is enough time for the connection issue to be solved.
[3]: http://www.joshmorony.com/genuitec-release-epic-debugger-gapdebug-for-phonegap-apps/ ‘Genuitec Release EPIC Debugger ‘GapDebug’ for PhoneGap Apps’