The promise of PhoneGap/Cordova development is quite alluring. Use your existing HTML/JS/CSS skills (and team) to build cross-platform mobile applications for iOS/Android, and other mobile platforms. As a bonus, you can then update your existing codebase once for all platforms instead of maintaining separate repositories (or paying specialized developers). This post will talk about some of the questions and decisions you should consider before beginning your next cross-platform Cordova project.
Cordova or PhoneGap?
This first choice might be a confusing one but it’s really very simple. PhoneGap is a product owned by Adobe which currently includes additional build services, and it may or may not eventually offer additional services and/or charge payments for use in the future. Cordova is owned and maintained by Apache, and will always be maintained as an open source project. Currently they both have a very similar API. I would recommend going with Cordova, unless you require the additional PhoneGap build services.
Which plugins will you use?
Plugins are a big part of the magic of Cordova development. Cordova ships with a minimal set of APIs, and projects add what extra APIs they require through plugins. You can search through all existing plugins using the Cordova Plugin Registry. The core set of “blessed” Cordova plugins provide access to Battery, Camera, Dialogs, Geolocation, and more, which are generally available across all supported platforms.
There are also many other third party plugins that allow extra functionality including native sharing, analytics, and many other platform and device-specific capabilities, however cross-platform support is typically more limited with third-party plugins. Make sure that you are aware of which plugins you will need and make sure that they are available on the platforms and versions you will be supporting. (Note: Cordova and PhoneGap use the same plugins.)
Which platforms and versions will you support?
For the most part it is trivial to support iOS6, iOS7, and iOS8, and Android 4.4 (KitKat, version 19), with Cordova-blessed and third-party plugins, and modern-browser-friendly HTML5 and CSS3. As an aside, both the Facebook and Twitter iOS apps only support iOS 6 and later. It is not as easy to support iOS5 and earlier as these versions have been deprecated in Cordova as of version 3.5.
The first generation iPad is locked at version 5.1.1, so those iPad users (and users who have not updated beyond iOS5) will not be able to download your app from the App Store unless you customize the application in XCode. Additionally, if you are going to support 64-bit iOS devices such as the iPhone 5S, you will either need to use a recent version of Cordova (3.5 or greater), or you will also need to do some further customization within XCode.
Support for legacy Android versions is a bit more complicated, depending on what your specific needs are. You will want to be familiar with the Android Developer dashboard for weekly updated stats about Android platform versions. Android versions 2.2 (Froyo, version 8) and earlier do not have Play Market, so those users won’t download your app. Android version 2.3 (Gingerbread, version 10) is officially warned against using in the Cordova Security Guide, and many third-party Cordova plugins do not support Gingerbread, so its use is discouraged. Android 3.x (Honeycomb, version 11-14) appears to have been completely phased out with zero percent of users in the weekly dashboard (so testing this version might be both complicated and completely worthless).
As far as worthwhile Android versions go, version 4.4 (KitKat, version 19) has excellent CSS3 & HTML support. You can most likely just build your working iOS Cordova app for android and view it in a 4.4.x version Android device and not have any issues at all. Versions 4.0 – 4.3 (Ice Cream Sandwich and Jelly Bean, versions 14-18) will likely require at least a little more effort, especially if you are using hardware-accelerated CSS 3D transforms or scrollable divs. You will probably spend the majority of your UI bug-fixing time working on these versions alone, however at the time of this writing, these versions (not including KitKat) enjoy a combined 63% global distribution, so this is time well spent in most cases.
Regarding CSS and platform support and version fragmentation, one approach that I recommend is similar to that used by Modernizr. You can use the Cordova device plugin to detect the OS and version (and other device-specific properties), and append specialized classes to the html or body elements, such as ‘ios’, ‘android’, and ‘jelly-bean’. This way you can target specific versions with CSS more easily. Another variation on this approach is to add a class such as ‘legacy’ for certain platform versions, to simplify the CSS selectors while still allowing for similar platform/version differentiation.
What form factors will you consider?
Will you support only mobile phone or tablet form-factors, or provide a responsive, universal experience? This question can dramatically change your designer, developer, and tester resource requirements for a given project. Just as each platform and platform version will introduce an extra level of effort, each form-factor/breakpoint setting will introduce a new level of effort for designers and developers.
Additionally, each level of effort for designers/developers will create a new level of effort for testing requirements for each platform version. That is to say that for a project with three supported versions with two identical form-factors, there are two levels of designer/developer effort and six levels of testing effort involved.
What about offline support?
What is your app going to do when there is no internet connection? While some apps don’t require any internet access for normal behavior (e.g. a calculator), some do. Take a moment to consider the user-experience for your app when no internet connection is present. Things that might not work while offline include sharing, linking (includes opening links in an in-app browser), analytics, and file access/transfer (ajax or otherwise). You can use the Cordova Network/Connection plugin to detect the connection type and to handle online and offline detection and event handling.
Are you handy with XCode and Eclipse?
There will probably be some things that you will not like about the out-of-the-box Cordova XCode implementation. For example, do you want the status bar to be hidden when you launch the app (and/or after the start screen)? Do you want to disable Universal application status? You might even want to customize some Cordova application settings or plugins (which are written in Objective-C). If you want to release your application to the App Store (or do some of the things just mentioned), then at some point you are going to have to learn some basics of XCode development. Most of the Android settings can be changed directly in the AndroidManifest.xml file so knowledge of the Eclipse IDE isn’t as essential, however you should be aware of how to sign and publish a Cordova app for Android.
How will you test the app?
It is a good idea to have one or two physical devices for each platform/version combo you are supporting. There are emulators and simulators that can help you to identify some major issues, but nothing beats having a real device for testing. With emulators sometimes you will get false positives or negatives for bugs (and sometimes the emulators have bugs of their own which don’t affect your application). It is also helpful to be aware of the any specific bugs and/or issues with the platforms/versions/devices you are testing.
Debugging Cordova applications can sometimes be a challenge, but if you are familiar with Chrome and Safari Dev Tools it is much easier. For Android devices, you should be able to choose Tools > Inspect Devices and have full access to your application’s HTML, CSS and JS. Similarly in iOS once debugging is enabled in iOS Safari and Mac Safari, you will have access to the Developer Panel with similar access (although with a very XCode-style debugging UI which might take some getting used to). You will need to reopen the Safari Developer panel whenever you restart your app, which can be a pain, but you can also simply reload the app with Command+R instead. Another approach I’ve used is to use setTimeout or an alert to delay the app for debugging so that I have time to open the console before the application starts up.
Hopefully this post will help you to think about the considerations for in-house cross-platform packaged application development with Cordova/PhoneGap. Mobile application development typically involves a lot of testing and iteration, so be sure to plan accordingly.
Interested in learning about Cocoa Touch Static Library vs. Cocoa Touch Framework? Read Kirk’s latest post here.