Performance Zone is brought to you in partnership with:

Raymond Camden is a developer evangelist for Adobe. His work focuses on web standards, mobile development and Cold Fusion. He's a published author and presents at conferences and user groups on a variety of topics. He is the happily married proud father of three kids and is somewhat of a Star Wars nut. Raymond can be reached via his blog at www.raymondcamden.com or via email at raymondcamden@gmail.com Raymond is a DZone MVB and is not an employee of DZone and has posted 213 posts at DZone. You can read more from them at their website. View Full User Profile

Building "Robust" PhoneGap Applications

03.21.2013
| 1879 views |
  • submit to reddit

Lately I've been thinking more about how to make my PhoneGap applications more robust. By robust, I'm not necessarily talking about performance. While that is important (see my coworker's excellent blog post on the topic: Performance & UX Considerations For Successful PhoneGap Apps), I'm thinking more about the general stability of the application as a whole. This is especially important for applications that need, or desire, data only available on the network. How you handle network conditions is just as important as how you handle the UX and performance of your application. (Well, that may be up to debate. :) In this blog post I'm going to share some thoughts and examples of what I mean by this and - as always - I look forward to your comments, suggestions, and corrections.

Net-Using PhoneGap Apps

It may seem silly to specify "Net-Using" PhoneGap applications, but to be clear, you are perfectly able to build a PhoneGap application that doesn't require any assets from the Internet. All of your HTML, CSS, and JavaScript can be packaged up with the application and if you have no real need to hit any remote sources, then don't! If you're used to loading the CDN version of JavaScript or CSS libraries, replace them with local copies.

That being said, if you do need to use the Internet in your application, how can you handle network issues? PhoneGap provides two different ways to handle this.

First is the Connection API. This isn't really an "API", but simply a constant you can check in your code to determine the connection status. There are various results that allow you to not only check for any connection but the relative strength of the connection. This would be useful, for example, to determine what quality of a YouTube video you want to display - standard or HD.

Here are the possible values for this constant:

  • Connection.UNKNOWN
  • Connection.ETHERNET
  • Connection.WIFI
  • Connection.CELL_2G
  • Connection.CELL_3G
  • Connection.CELL_4G
  • Connection.NONE

One of the constant values for the Connection object is UNKNOWN. How you handle that is really up to you. In general, I think it is safer to be pessimistic and assume UNKNOWN is the same as OFFLINE, but I go back and forth on that.

The second thing PhoneGap provides is an event system that can recognize network changes. You have both an offline and online event your code could listen to.

In general, I think it makes sense for an application to check network status on startup, and have event listeners for changes. You can't assume that a network connection that exists when the application starts up will be there for as long as the application is alive.

In order to test this, I build an application that supports Twitter searches. If you are online, then you can enter a search term, hit the button, and see the results from the Twitter API. If you are offline, the application responds correctly. The code I used also handles your device going on and offline. Here is a portion of the code.

document.addEventListener("deviceready", init, false);

function init() {
  document.addEventListener("online", toggleCon, false);
	document.addEventListener("offline", toggleCon, false);

	if(navigator.network.connection.type == Connection.NONE) {
		navigator.notification.alert("Sorry, you are offline.", function() {}, "Offline!");
	} else {
		setupButtonHandler();
	}

}

function toggleCon(e) {
	console.log("Called",e.type);
	if(e.type == "offline") {
		$("#searchBtn").off("touchstart").attr("disabled","disabled");
		navigator.notification.alert("Sorry, you are offline.", function() {}, "Offline!");
	} else {
		$("#searchBtn").removeAttr("disabled");
		navigator.notification.alert("Woot, you are back online.", function() {}, "Online!");
		setupButtonHandler();
	}
}

For the most part, this should just "make sense", but definitely let me know if you have questions. (I've included the entire application as a zip attached to this blog entry. It really isn't much more than this, but if you want to see it, just download the bits.)

Here's an example of the application running in Ripple. Notice that I've done a search already.

I can now use Ripple to take my device offline. Notice that Ripple fakes an in-device notification with a simple HTML element overlaying the device.

It may be a bit hard to see, but the button has been disabled as well. This way the user can't accidentally click it again. When network access is restored, the button will be re-enabled.

Error Handling

Here is something that I've really done a poor job of. Many of PhoneGap's APIs, and most remote APIs, have some way of handling errors. But I'd be willing to bet most of your error handlers look something like this.

function errHandler(e) {
console.dir(e);
alert("Sorry, an error. It happened. Deal with it.");
}

Ignoring for a moment that the message is a bit rude, note that no attempt was made to diagnose the form of the error and make a logical decision as to what should be done. Not every error is a "Throw your hands up in the air and give up" exception. In many cases, it may be something that is purely temporary and you should prompt your user to try again. In other cases it may be so bad you would want your application to shut down. The main point I'd want you to take from this is to consider the types of errors you may be handling and try to react to them as nicely as possible. If you have error gotten a weird, obtuse error in an application before and wanted to pull your hair out, keep in mind that you're a developer. Imagine what the normal people think.

Remember that JavaScript has full exception handling with try/catch support, the ability to throw your own exceptions, as well as listening for errors at the window level.

Finally, don't forget you can Lint/JSHint your code. For folks new to JavaScript that can be a bit intimidating, but if you go in with the mindset that you don't necessarily need to agree with everything the Lint/Hint says, then the experience isn't quite as jarring. Of course, if you use Brackets you get JSLint built in. (You can also find an extension for JSHint.)

Tracking/Reporting Issues

So here's an interesting one. Imagine you've got your application making use of the CowBell API. You've got nice error handling/connection handling in place. You've made the experience great for the end user. But are you responding to these errors and events? Are you cognizant of just how often the CowBell API goes down? Maybe it isn't so bad. Maybe it is pretty crappy. But until you start getting a bunch of 1-Star reviews you may not necessarily be aware of it.

Maybe it isn't too bad. For example, only 10% of the calls fail. That isn't terrible, but it is probably enough to warrant looking into app-side caching. You can make use of LocalStorage or the Storage API. Heck you can use the File system too. On the flip side, if your API has something like 100% uptime and your users are in an an area with darn good coverage, it may not be worth your development time to worry about it.

The point is - how do you know?

During internal testing, you could make use of simple code that logs to a local file. You can add a temporary button to upload that file to a central server. While your users are testing, they can make use of that button then to upload their local logs when something is acting up.

Of course, you could do the same thing on a released, production application as well. How much you track and how you upload is more an ethical question than a technical one, but that option exists as well.

You can consider using a third party JavaScript error-handling solution, like {errorception}. However - I do not know if they support PhoneGap apps. When I find out, I'll edit this post. I've found their results to be incredibly detailed and useful for my desktop apps.

What else?

So I know I'm missing other suggestions. Leave a comment below!

Download attached file



Published at DZone with permission of Raymond Camden, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)