PhoneGap for Flex/AIR Mobile Developers

If you’re a Flex/AIR developer or any developer focused on mobile for that matter, I believe it’s worth your while to spend some time reading this first post in a series of posts I will be writing on usingPhoneGap (aka Cordova) for building mobile apps. It’s another great technology choice for rapid cross-platform mobile development and becoming more and more popular. I’ve heard some developers express how they feel like they’re going back in time with HTML/JS development, or simply don’t want to ‘go there’ but it’s worth checking out how it can be used to quickly build a mobile application with HTML/JS and PhoneGap and you should consider this option for building mobile apps.

What is it?

The crux of PhoneGap is essentially a big ‘ol .js file (per platform, separate one for iOS vs Android etc) along with some simple native code to enable it to work. In the main JavaScript file (phonegap.js or cordova.js) are a bunch of functions that give you access to native features including the camera, compass, accelerometer, file system, storage access, media capture, audio playback, notifications, contacts and network connection status etc, similar to what Adobe AIR APIs offer, with the addition of a couple more. You write your applications in HTML/JavaScript and use CSS to style them. PhoneGap apps are wrapped in a native web container component, which is why your HTML/JS/CSS work. This also means there is a dependency for your phone’s browser to be based on the WebKit engine. This really isn’t an issue though since WebKit is the default for iOS, Android, BlackBerry Tablet OS and webOS currently. A great overview ofcommonly asked questions about PhoneGap can be found on my teammate Andy Trice’s blog, as well as a bunch of other great PhoneGap posts, so definitely check out his blog for heaps of good content.

How Does it Work?

The API functions in the phonegap.js (or most recently cordova.js) files call native plugin/extension code to provide the access to the native features through JavaScript exec calls. If you’re an AIR developer, it’s similar to the AIR Native Extensions model, except in PhoneGap they’re called plugins, and the set of APIs listed above (notifications, compass etc) are included and set up for you by default in the PhoneGap download. There are a bunch of other open source plugins available too which can easily be added to your project, or if you don’t find one you need, they’re easy to write. Here you can find instructions on how to write one for Android, and here for iOS. You can see that the JavaScript exec calls for iOS use .h/.m files for the actual native implementation, and .java for Android.

When you’re ready to use one of the APIs in your application, it’s very straightforward and easy to use. Here’s an example of adding a notification to your application:

Code Example

1
2
3
4
5
6
7
8
9
10
...
    function showAlert() {
        navigator.notification.alert(
            'You are the winner!'// message
            alertDismissed,         // callback
            'Game Over',            // title
            'Done'                  // buttonName
        );
    }
...

Here’s the result:

You will find that all of the APIs are accessed through a navigator variable (declared in the phonegap.js file). To see examples of how to use all of them, check out the nicely done API reference docs.

If you’re curious of how this works underneath, here’s the notification code snippet straight out of the cordova.js file (NOTE: remember phonegap and cordova are currently the same library, so if you download it now you may find that your main API files are named cordova.js file instead of phonegap.js):

phonegap.js Source for Notifications

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
...
/**
 * Open a native alert dialog, with a customizable title and button text.
 *
 * @param {String} message              Message to print in the body of the alert
 * @param {Function} completeCallback   The callback that is called when user clicks on a button.
 * @param {String} title                Title of the alert dialog (default: Alert)
 * @param {String} buttonLabel          Label of the close button (default: OK)
 */
Notification.prototype.alert = function(message, completeCallback, title, buttonLabel) {
    var _title = title;
    if (title == null || typeof title === 'undefined') {
        _title = "Alert";
    }
    var _buttonLabel = (buttonLabel || "OK");
    <strong>Cordova.exec(completeCallback, null, "org.apache.cordova.notification", "alert", [message,{ "title": _title, "buttonLabel": _buttonLabel}]);</strong>
};

The above code shows the notification alert function definition to use for performing a native alert notification on iOS. The important line there is the Cordova.exec(…) call, which will use the native plugin code for iOS or Java to perform the notification. If you’re extra curious and want to see what the native code looks like for this, you can open the Notification.java or CDVNotification.m files such as shown (note: you need to download the actual cordova/phonegap project source from github here to view the source files for the core plugins. This is only necessary if you wish to view them or want to make your own custom changes to them, typically you would just install from here). I pasted a couple snippets from the native code files below to give an idea:

Java Source for Notifications

1
2
3
4
5
6
7
8
9
10
11
12
13
public PluginResult execute(String action, JSONArray args, String callbackId) {
    PluginResult.Status status = PluginResult.Status.OK;
    String result = "";  
    
    try {
      ...
      else if (action.equals("alert")) {
        this.alert(args.getString(0),args.getString(1),args.getString(2), callbackId);
        PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
        r.setKeepCallback(true);
        return r;
      }
...

Objective-C Source for Notifications

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
...
- (void) alert:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
{
    int argc = [arguments count];
    NSString* callbackId = argc > 0? [arguments objectAtIndex:0] : nil;
    NSString* message = argc > 1? [arguments objectAtIndex:1] : nil;
    NSString* title   = argc > 2? [arguments objectAtIndex:2] : nil;
    NSString* buttons = argc > 3? [arguments objectAtIndex:3] : nil;
    
    if (!title) {
        title = NSLocalizedString(@"Alert", @"Alert");
    }
    if (!buttons) {
        buttons = NSLocalizedString(@"OK", @"OK");
    }
    
    CDVAlertView *alertView = [[CDVAlertView alloc]
                              initWithTitle:title
                              message:message
                              delegate:self
                              cancelButtonTitle:nil
                              otherButtonTitles:nil];
    
    alertView.callbackId = callbackId;
    NSArray* labels = [buttons componentsSeparatedByString:@","];
    int count = [labels count];
    
    for(int n = 0; n < count; n++)
    {
        [alertView addButtonWithTitle:[labels objectAtIndex:n]];
    }
    
    [alertView show];
    [alertView release];
}
...

Common Questions

    • What kind of UI Components does PhoneGap offer? PhoneGap does not offer UI Components, they leave that implementation up to you with your choice of HTML/JS/CSS or some other UI frameworks available like Twitter Bootstrap, jQuery Mobile, Kendo UI etc…
    • How can I consume data in a PhoneGap app? The same way you consume data from a web application – REST, JSON, SOAP etc.
    • What’s the difference between PhoneGap and Cordova? Cordova is the Apache Open Source project behind PhoneGap. If this is confusing to you, please read this post!
    • What kind of development environment do I need? You can develop in your editor of choice on any platform. There are some workflow tips I can provide and will do so in the next post with my choices for editing, debugging etc. Once you have created your app in your platform of choice, you can just upload the source directly from your source control system or via zip file to PhoneGap Build as the screenshot below shows and it will create a ready to install package for all of the different platforms.

(http://devgirl.org/2012/05/14/phonegap-for-flexair-mobile-developers/)