5. The Mechanics of Cordova Development

Now that you have a Cordova development environment configured and you know all about the CLI commands available to you, it’s time to show you the process of developing, testing, and debugging Apache Cordova applications.

There are some processes and capabilities that apply across all supported mobile device platforms. In this chapter, I’ll address the mechanics of Apache Cordova development. I’ll begin the chapter by addressing some of the issues a Cordova developer must deal with, then I’ll cover the development process and some of the tools you can use to test and debug your Cordova applications. I’ll even show you how to customize the web application content for your application for different mobile device platforms.

Cordova Development Issues

Before we start discussing how to develop Cordova applications, let’s first address some of the issues that you will face as you work with the framework. The Cordova project is supported by developers from all over the world, developers who may have experience with only one or a small number of mobile platforms, developers who have a strong opinion about how something should be done. The problem with this is that when you try to collect development projects written by different people into a single framework, you will likely bump up against some inconsistencies. Add to this the fact that every mobile platform supported by Cordova is different and has different ways of doing things, and you have a difficult task to make everything work cleanly and seamlessly.

The good news is that over time, the Cordova development team has done an amazing job in eliminating most of the cross-platform issues. All that’s left are two, and they’re not that complicated.

Dealing with API Inconsistency

Figure 5.1 shows the supported feature matrix from the PhoneGap web site (the Cordova team doesn’t seem to publish a matrix); you can find the page at http://phonegap.com/about/feature. As you can see, the table is pretty complete; there are some gaps, but it’s more full than empty. If a particular feature you want to use in your application is supported only on some mobile platforms, you’ll have to make special accommodation within your application for platforms that do not support the particular API (or you can write the code to support it and contribute it to the project Image).

Image

Figure 5.1 Supported Features Matrix


Warning

Keep in mind that the table is not updated as often as the API, so you may want to validate through the API documentation or through actual testing of an API whether or not it works on a platform for which there’s an X in the figure.


One of the things you can do is check for the existence of the API object your application will be calling:

if (navigator.camera) {
  //We have a Camera, so do something with it

} else {
  //No Camera, sorry, warn the user or take an alternate path

}

If your application uses an API that isn’t supported on all of the mobile devices that your application will target, your application’s code can use the Device API discussed in Chapter 13, “Using the PhoneGap CLI,” to try to figure that out. Your application should use device.platform and, as necessary, device.version to determine which platform and OS the application is running on and disable an unsupported feature if the application is running on a device that doesn’t support the API.

Another option is to simply wrap the call to a particular API with a JavaScript try/catch block and deal directly with any failures that occur. Unfortunately, most Cordova APIs fail silently, so you may not see an exception to catch.

Application Graphics, Splash Screens, and Icons

Each mobile platform and often different versions of a particular device OS have different requirements for application icons and splash screens. Developers building Cordova applications for multiple device platforms need to be prepared to create a suite of graphics for their applications that address the specific requirements for each target device platform and/or device OS.

Additionally, for some devices on some carriers (older BlackBerry devices, for example), the mobile carrier applies a specific theming to the OS in order to help distinguish itself in the market. Any application icon designed for one of these devices will need to accommodate, as much as possible, rendering pleasantly within different themes.

Fortunately with the merges capabilities described later in this chapter, you have the ability to easily merge in the appropriate graphics files (and other content as needed) depending on which mobile platform you are building for.

For application icons, the PhoneGap project maintains a wiki page listing the icon requirements for the different supported operating systems here: http://goo.gl/rfPULW.

Creating splash screens and application icons is a pain since you have to deal with many different screen and icon resolutions. Several developers have built Node modules you can use to generate splash screens and/or application icons for multiple mobile device platforms:

Image Cordova Media Generator (www.npmjs.org/package/cordova-media-generator)

Image Cordova Gen (www.npmjs.org/package/cordova-gen)

Image Cordova Gen Icon (www.npmjs.org/package/cordova-gen-icon)

As the default folder structure for Cordova projects has changed for Cordova 4, these modules may have some issues. Ideally each will be updated by the time you read this.

I’m not going to cover how to set up the application icons for your Cordova projects since a Cordova application is just a native mobile application, and the way you configure your icons has nothing to do with Apache Cordova—it’s just the way native application projects are configured. Refer to the documentation for the mobile device SDK for information on how to configure application icons for the platforms you use.

Developing Cordova Applications

Now it’s time to start working through the process of how to create Cordova applications. In this section, I’ll describe the process for coding a Cordova application. In later sections, I’ll show you how to test and debug applications.

To create a new project using the Cordova CLI, you will need to open a terminal window, navigate to the folder where you want the project folder created, and use the cordova create command. Next, you will need to change directories (using the OS cd command) to the folder created by the cordova create command. Once there, you can add platforms and plugins to your project as needed; the series of commands will look something like the following:

cordova create app_name
cd app_name
cordova platform add platform_name
cordova plugin add plugin_name

In this example, app_name refers to the name of the application you are creating, and platform_name refers to the mobile device platform you will be working with. So, if I were creating an Android application called lunch_menu, I would issue the following commands:

cordova create lunch_menu
cd lunch_menu
cordova platform add android

You can also specify more information about your application by using the following:

cordova create lunch_menu com.ac4p.lunchmenu "Lunch Menu"
cd lunch_menu
cordova platform add android

At this point, the CLI would create the Cordova project folder shown in Figure 5.2, and all you would need to do is open your code editor of choice and start coding and testing your new Cordova application.

Image

Figure 5.2 Cordova Application Project Folder Structure—Android Application

The question, though, is where to edit the web application content. If you look at the project folder structure shown in Figure 5.2, you will see that there are two folders called www: one in the Android platform folder structure and another off the project root folder.

The project’s www folder (the www folder highlighted in the lower half of Figure 5.2) contains the web application files that you will create for your application. During the prepare step, all of the files in the folder are copied to the platform-specific www folder(s) (in this case, the Android project folder highlighted in the top of Figure 5.2). I’ll explain a little more about how this works later in the chapter.


Note

You may be asking yourself, “Why can’t I edit the web application content in the platform-specific www folder?”

You can, but when you run the cordova prepare command, or execute any other Cordova CLI command that performs a prepare, the content in the platform-specific folder will be overwritten by the content from the project’s www folder. Because of this, it’s always best to edit the content in the project’s www folder.

If you have platform-specific content you want to add to your project, use the merges capability described later in the chapter.


Because Cordova is all about cross-platform mobile development, you’re probably going to want to target multiple mobile device platforms. In that case, if you were, for example, building an app for Android and iOS, you would open up a terminal window and do something like the following:

cordova create lunch_menu
cd lunch_menu
cordova platform add android firefoxos ios

At this point, what you’d have is a Cordova project structure with separate projects for Android, Firefox OS, and iOS as shown in Figure 5.3.

Image

Figure 5.3 Cordova Application Project Folder Structure for Multiple Platforms


Note

Notice that in the last two figures I’m switching between Windows and OS X—that’s because this works exactly the same no matter what OS you are running on.


You will still work with the web content stored in the project’s www folder shown at the bottom of the folder structure in Figure 5.3. When you have the web application content in that folder ready for testing, you will use the cordova prepare command to copy the code into the platforms subfolders shown in the figure.

What I do while working on a Cordova project is keep my web content files open in an HTML editor like Adobe Brackets (www.brackets.io) or Aptana Studio (www.aptana.com), then use the CLI to manage my mobile device platform projects for me. As I edit the files, adding the web content to the .html file and my application’s code to the application’s .js files, when I’m ready to test (and debug) the applications I switch over to a terminal window that I keep open and pointed to the Cordova project’s root folder (the lunch_menu folder I created a while back) and issue the commands I need to prepare my content and execute the application in a simulator or on a device.

To copy the web application content to each target platform, I would use the following:

cordova prepare

What this command does is copy all of the files from the www folder into the appropriate folder for each specified mobile platform project as shown in Figure 5.4. In this example, it copies the content files to the Android project’s assets/www folder, the Firefox OS project’s www folder, and the iOS project’s www folder.

Image

Figure 5.4 Copying Web Content to the Platform Projects Folders

To copy the web application content to the project folder for a specific platform, I would specify the target platform on the command line:

cordova prepare android

Or, if I will be testing and debugging both the Android and Firefox OS versions of the application, I issue the following command:

cordova prepare android firefoxos

Now, so far in this process, I’ve not added any plugins to this project. While you can build a Cordova application and not use any plugins, most developers choose Apache Cordova because it provides a web application with access to native APIs. So, for my project, I’m going to add some plugins by returning to my terminal window and issuing the following commands:

cordova plugin add org.apache.cordova.console
cordova plugin add org.apache.cordova.device
cordova plugin add org.apache.cordova.dialogs

This will add the Console, Device, and Dialogs plugins to the project (described in Chapter 14, “Working with the Cordova APIs”). When you look at the project folder structure, you should see that there’s now some new stuff in the project’s plugins folder as shown in Figure 5.5.

Image

Figure 5.5 Cordova Application Project Folder Structure with Plugins

Each plugin should have its own folder as shown in the figure. Remember that some plugins depend on other plugins, so if you see more plugins listed there than you know you installed, it’s probably because the CLI installed any required plugins automatically.

There’s nothing special you have to do to use these plugins; simply make the appropriate calls to the associated APIs and you’re all set.

The plugins folder contains individual .json configuration files for each target platform supported by the project; you can see an example of the android.json file in Listing 5.1. The files contain metadata used by Plugman to manage the plugins.

Listing 5.1 android.json File


{
  "prepare_queue": {
    "installed": [],
    "uninstalled": []
  },
  "config_munge": {
    "files": {
      "res/xml/config.xml": {
        "parents": {
          "/*": [
            { "xml": "<feature name="Notification"><param name="android-package"
            value="org.apache.cordova.dialogs.Notification" /></feature>",
            "count": 1 },
            { "xml": "<feature name="Device"><param name="android-package"
            value="org.apache.cordova.device.Device" /></feature>",
            "count": 1 }
                ]
        }
      }
    }
  },
  "installed_plugins": {
    "org.apache.cordova.console": {
      "PACKAGE_NAME": "com.ac4p.lunchmenu"
    },
    "org.apache.cordova.dialogs": {
      "PACKAGE_NAME": "com.ac4p.lunchmenu"
    },
    "org.apache.cordova.device": {
      "PACKAGE_NAME": "com.ac4p.lunchmenu"
    }
  },
  "dependent_plugins": {}
}


Now, any self-respecting mobile web project may have some icons, screen graphics, CSS, and/or JavaScript files that are unique to each target platform. Since each mobile device has its own theme and icon requirements, it’s likely that at a minimum those will be required. In older versions of Cordova, the developer had to manage all of that manually; with the CLI that’s all taken care of for you.

To support platform-specific resources, what you’ll need is some way to tell the Cordova CLI what files belong to which platform. The www folder you’ve been working in is not the right place for this as having an extra level of folders in your project folder would further complicate things when you simply want the Android files in the Android project, the iOS files in the iOS project, and so on.

To accommodate this need, the Cordova CLI uses a special folder called merges to manage the platform-specific files. To implement this, add a folder called merges to your Cordova project folder, then create subfolders (under merges) for each target platform. With the folders in place, place the platform-specific content (images, HTML pages, JavaScript files, whatever) in the appropriate folder. Figure 5.6 shows the merges folder structure in my Cordova Lunch Menu project.

Image

Figure 5.6 Cordova Application Project Folder Structure with Merges

With the merges folder structure in place, you’re ready to go. When you issue the cordova prepare commands shown earlier, the CLI will copy the custom content for each of the platforms into the appropriate web content folder for each platform’s project folder as shown in Figure 5.7.

Image

Figure 5.7 Copying Web Content and Platform-Specific Content to the Platform Projects Folders

As shown in the figure, custom content for the Android platform stored in the mergesandroid folder will be copied into the Android platform project’s assetswww folder. Custom content for iOS applications will be copied from mergesios to the iOS project’s www folder.


Note

In earlier versions of Apache Cordova, the merges folder was automatically created. For some bizarre reason, the Cordova dev team decided to remove the folder from the default project in order to avoid confusing users. So, instead of seeing the folder there and being able to quickly determine what it’s for (by reading the documentation, for example), you now have to know the capability exists and manually create the necessary folder structure to implement this feature for your applications. Sigh. In Chapter 6, “Automation and the Cordova CLI,” I’ll give you some tools you can use to automate creation of the necessary merges folder.


With all of the application’s content copied into the appropriate project folders, you can open the appropriate IDE (Eclipse for Android, Firefox for Firefox OS, and Xcode for iOS) and begin the testing process. For information on how to import the Cordova projects into each IDE and use the platform’s debugging tools, refer to Chapters 7 through 11.

One of the things I’ve not covered yet is the concept of hooks. You may have noticed that most of the figures in this section show a hooks folder. You use the hooks folder to provide code that executes at different times during the CLI’s processing of your project. I am not going to cover this now; instead, I show how hooks work in Chapter 6.

Configuring a Cordova Application

At the top of Figure 5.6, you can see the config.xml file; it’s the configuration file for a Cordova project. The file is a standard XML file and originally aligned with the W3C’s Widget specification (www.w3.org/TR/widgets/). Over time, the Cordova development team has moved away from the specification and started allowing additional capabilities to be added to the file.

The config.xml file is primarily used to define project-level settings for the application. There are platform-specific config.xml files used by Cordova as well. I’m not going to cover every aspect of the config.xml here, only the project-level settings; refer to the Cordova documentation for additional details at http://goo.gl/86AQeU.

Listing 5.2 shows the default project config.xml file updated with information for my Lunch Menu application.

Listing 5.2 Cordova Project config.xml File


<?xml version='1.0' encoding='utf-8'?>
<widget id="com.ac4p.lunchmenu" version="0.0.1"
  xmlns="http://www.w3.org/ns/widgets"
  xmlns:cdv="http://cordova.apache.org/ns/1.0">
  <name>Lunch Menu</name>
  <description>
    Company lunch menu application.
  </description>
  <author email="[email protected]" href="http://www.johnwargo.com">
    John M. Wargo
  </author>
  <content src="index.html" />
  <access origin="*" />
</widget>


Table 5.1 provides a description of each of the properties of the config.xml file shown in Listing 5.2.

Image

Table 5.1 config.xml Options

Regarding the content element, there’s nothing saying you can’t populate it with an external URL:

<content src="https://www.cordova4programming.com/" />

With this in place, when the application starts, it will connect to the specified URL (this book’s web site) and load the content from that server into the WebView. With this approach, you’re essentially creating a browser application that points to a specific site. As much fun as this is, keep in mind that Apple will likely not allow you to publish an application that does this to the Apple App Store. They tend to frown upon applications that don’t have any content of their own.

There are some additional preferences elements that can be added to the file as well. These preferences apply to all mobile device platforms.

The Fullscreen preference is used to control visibility of the status bar. The default value is false, so if the preference is missing, the status bar will be shown at the top of the screen. To hide the status bar, add the following preference element to the project’s config.xml:

<preference name="Fullscreen" value="true" />

Using the Orientation preference, you can lock the device orientation; this allows you to prevent the interface from rotating in response to changes in orientation. Possible values for this preference are default, landscape, and portrait. With the default setting, or with the preference omitted, the application will respond, and change layout, when the device is in portrait or landscape mode. To lock the application into landscape mode, add the following preference element to the config.xml:

<preference name="Orientation" value="landscape" />

There are some other preferences that apply to a subset of mobile device platforms.

On Android and BlackBerry, you can force the application background color, overriding CSS settings, for the application using the BackgroundColor preference:

<preference name="BackgroundColor" value="0xff0000ff"/>

For this preference, set the value property to a 4-byte hexadecimal color value. In this value, the first byte represents the alpha channel and the subsequent 3 bytes the RGB values. In the example shown, the background color is being set to blue (0000ff).

For Android and iOS devices, you can control what happens in the application when the user tries to scroll past the beginning or end of the page content using the DisallowOverscroll preference:

<preference name="DisallowOverscroll" value="true"/>

The default setting for this preference is false. On iOS, when the user scrolls past the top or bottom of the content, the page will bounce back to its original position. On Android, the top or bottom edge of the content will be highlighted with a glowing effect.

Set this preference to true as shown in the example to configure the application so it does not display any feedback when the user tries to scroll past the top or bottom of the page.

On BlackBerry and iOS, you can use the HideKeyboardFormAccessoryBar preference to hide an additional toolbar that appears above the default keyboard which provides options to help users navigate from one input field to another.

<preference name="HideKeyboardFormAccessoryBar" value="true"/>

The default for this preference is false.

Listing 5.3 shows an example config.xml file with several of these preferences elements added.

Listing 5.3 Cordova Project config.xml File with Preferences


<?xml version='1.0' encoding='utf-8'?>
<widget id="com.ac4p.lunchmenu" version="0.0.1"
  xmlns="http://www.w3.org/ns/widgets"
  xmlns:cdv="http://cordova.apache.org/ns/1.0">
  <name>Lunch Menu</name>
  <description>
    Company lunch menu application.
  </description>
  <author email="[email protected]" href="http://www.johnwargo.com">
    John M. Wargo
  </author>
  <content src="index.html" />
  <access origin="http://myserver.com" />
  <preference name="Fullscreen" value="true" />
  <preference name="Orientation" value="default" />
</widget>


The config.xml file is also used to configure PhoneGap Build projects; you will learn more about this topic in Chapter 12, “Using PhoneGap Build.”

Testing Cordova Applications

Each of the mobile platforms supported by Cordova has processes and tools a developer can use to test and, in the unlikely event your code has bugs, debug Cordova applications.

Most mobile device manufacturers provide a software program that emulates or simulates a mobile device. This allows developers to easily test their mobile applications when they don’t have a physical device. Performance isn’t usually the same, but they look and act like real devices as much as they can. In some cases what’s provided is generic and simply mimics the capabilities of the specific OS version, while for other mobile platforms the emulator or simulator might mimic specific devices. Either way, there’s a software-only solution available that developers can use to test Cordova applications in an almost real-world scenario. Google, for example, provides Android emulators, and Apple and BlackBerry provide simulators of their devices.

In Chapter 4, “Using the Cordova Command-Line Interfaces,” I showed you how to run your applications on physical devices or simulators using the Cordova CLI run command. There are also third-party solutions you can use to test your Cordova applications within a desktop browser interface. In Chapters 7 through 11 I’ll show you how to use the tools provided by the mobile device manufacturers.

Leveraging Cordova Debugging Capabilities

As you test your Cordova applications, you’re likely to run into issues that you’ll need to resolve. The purpose of this section is to highlight some of the debugging capabilities that are available to you outside of an IDE.

Using alert()

One of the simplest, and often most annoying, ways to debug a Cordova application is to use the JavaScript alert() function to let you know what part of the code you’re running or to quickly display the contents of a variable. I’ve always called this approach “the poor man’s debugger,” but it works quite well for certain types of application debugging tasks. If you see an event that’s not firing within your application or some variable that’s not being set or read correctly, you can simply insert an alert() that displays a relevant message and use that to see what’s going on.

As I started working with PhoneGap and PhoneGap Build, I noticed that there were many times when the deviceready event wasn’t firing in my applications. I would write my application and start testing it only to find that none of the PhoneGap APIs were working. In some cases, it was because the PhoneGap Build service wasn’t packaging the phonegap.js file with the application. In other cases it was simply because I had some stupid typo in the application that I couldn’t see.


Warning

Cordova fails silently when it encounters a JavaScript error, so if you have a typo in your code, the code will simply not run.


If you look at some of the example applications in Chapter 2, “Anatomy of a Cordova Application,” you’ll notice that most of the applications I show there have a call to alert in the onBodyLoad function. This allows me to know for sure that the deviceready event is firing; I always remove the alert before putting the application into production.

When I was writing all of the sample applications for PhoneGap Essentials, I even went as far as to put an alert at the beginning of every function in the application. As I figured out how and when each event fired, I would use the alerts to help me tell what was going on. Now, there are easier ways to do that, which I will show you in the next section, but this was just a simple approach to help me as I got started with each API.


Warning

Those of you who know a little bit about the Cordova APIs might be asking yourselves why I am talking about using alert() rather than the Cordova navigator.notification.alert() function.

Well, in the onBodyLoad() function, it is highly likely that cordova.js hasn’t loaded yet, so I can’t be sure that the Cordova navigator.notification.alert() will even be available. I can use navigator.notification.alert() in the onDeviceReady() function because the only time that function runs is when the Cordova deviceready event has fired. If you look at the sample applications throughout this book, you’ll notice that I always use the JavaScript alert method until I know for sure the deviceready event has fired, then switch to the Cordova alert for all other notifications.


Writing to the Console

The problem with using the approach described in the previous section is that when you fill your buggy code with alerts, you’re constantly interrupting the application flow to dismiss the alerts as they come up. For a simple problem, this approach works pretty well, but when debugging more troublesome errors, you will need an approach that allows you to let the application run, then analyze what is happening in real time or after the application or a process within the application has completed, without interrupting the application. Cordova applications can do this through the JavaScript console object implemented by the browser.

Using the console object, developers can write messages to the browser’s console which can be viewed outside of the running program through capabilities provided by the native SDKs or device simulators. The console object has scope at the window level, so it’s essentially a global object accessible by any JavaScript code within the application. Cordova supports several options; the most common ones used are

Image console.log("message");

Image console.warn("message");

Image console.error("message");

Beginning with Cordova 3.0, the console has been removed from the core Cordova APIs and is instead available as a plugin. To add console capabilities to your Cordova project, you should open a terminal window, navigate to the project folder, and issue the following command:

cordova plugin add org.apache.cordova.console

However, most device browsers support this by default anyway, so you may find that for some platforms it is not necessary.

Now, let’s take a look at a sample application that illustrates the use of this feature as shown in Listing 5.4.

Listing 5.4 Example Application That Writes to the Console


<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width,
      height=device-height, initial-scale=1.0,
      maximum-scale=1.0, user-scalable=no;" />
    <meta http-equiv="Content-type" content="text/html;
      charset=utf-8">
    <script src="cordova.js"></script>
    <script>
      function onBodyLoad() {
        document.addEventListener("deviceready", onDeviceReady,
          false);
      }
      function onDeviceReady() {
        //Just writing some console messages
        console.warn("This is a warning message!");
        console.log("This is a log message!");
        console.error("And this is an error message!");
      }
    </script>
  </head>
  <body onload="onBodyLoad()">
    <h1>Debug Example</h1>
    <p>Look at the console to see the messages the application
    has outputted</p>
  </body>
</html>


As you can see from the code, all the application has to do is call the appropriate method and pass in the text of the message that is supposed to be written to the console.

Figure 5.8 shows the messages highlighted in the Xcode console window. This window is accessible while the program is running on an iOS simulator, so you can debug applications in real time. Xcode adds the word WARN to the output for warning messages and adds ERROR to any error messages, so you can more easily locate these messages in the console.

Image

Figure 5.8 Cordova iOS Application Output Log in Xcode

In the Android SDK LogCat (explained in Chapter 7, “Android Development with Cordova”), console messages are highlighted (in green) as shown in Figure 5.9. Older versions of the SDK would color-code each message type in a different color—yellow for warnings and red for errors—but that feature seems to have been removed.

Image

Figure 5.9 Cordova Android Application LogCat Output in Eclipse

Remember that in the previous section I mentioned that the JavaScript code in a Cordova application fails silently? Well, you can also wrap the code in a try/catch block so your application will at least have the chance to write its error to the console as shown in the following example:

try {
  console.log("Validating the meaning of life");
  someBogusFunction("42");
} catch (e) {
  console.error("Hmmm, not sure why this happened here: " +
    e.message);
}

Notice that in Figure 5.9 for Android the LogCat shows the line number where the console message was generated. This will at least help you identify information about where the application is failing. You could also use an alert here, but that’s slightly less elegant.

You can also format your output without having to add strings together:

console.error("Hmmm, received an error (%s)", e.message);

In this case, the %s is replaced by the string stored in e.message. This isn’t a Cordova thing; it’s just how the console object works in the browser. You can pass multiple values into the string, using %s for strings, %i for numbers, and so on.

Debugging and Testing Using External Tools

There’s a very active partner community supporting Cordova with additional tools for Cordova developers. In this section, I’ll introduce a couple of the more popular tools that help developers test and debug Cordova applications. This is by no means a complete list of options; refer to the PhoneGap Tools page (http://phonegap.com/tool/) for information on additional tools that might be available. There are also some built-in debugging tools available with several of the mobile SDKs. These tools will be covered in the individual chapters for each mobile OS (Chapters 7 through 11).


Tip

One of the things I realized as I worked on this chapter as well as some of the other chapters that cover remote debuggers (Chapters 7 through 10) is that the format of a web application project matters. In most of my sample Cordova applications, I typically coded the application’s HTML and JavaScript code in the same file. If the application wasn’t that large, having everything in the same file made it easier for me to edit and debug my applications. As you’ll see next, weinre, and many of the other remote debugging tools, aren’t able to set breakpoints and debug JavaScript code embedded in an HTML file.

So, to make your work easier, be sure to split out your web application’s JavaScript into a separate file (index.js, for example) wherever possible. You’ll be glad you did later.


Weinre

Web Inspector Remote (weinre) is a community-built remote debugger for web pages. It was donated to the PhoneGap project and is currently implemented as part of the PhoneGap Build service. You can find the download files and instructions at http://goo.gl/hG7r0L.

For Cordova development, it allows a developer to remotely debug a web application running in a Cordova container on a physical device or a device simulator. Weinre consists of a debug server, debug client, and debug target. The debug server runs on Macintosh or Windows, and the debug client runs in any compatible desktop browser. Throughout this section I’ll demonstrate what you can do with weinre.

To configure weinre, you need to perform a series of steps. The process begins with the server installation. Weinre is Node-based, and since we already have Node installed for the Cordova CLI, you can install the weinre server using the following command:

npm install –g weinre

Unfortunately on Macintosh weinre may not like your security configuration, so even though it’s not recommended, you may have to install weinre using sudo with the following command:

sudo npm install –g weinre

After the installation completes, you should see a message similar to the following:

C:UsersjwargoAppDataRoaming pmweinre ->
C:UsersjwargoAppDataRoaming pm ode_modulesweinreweinre
[email protected] C:UsersjwargoAppDataRoaming pm ode_modulesweinre
+-- [email protected]
+-- [email protected] ([email protected])
+-- [email protected] ([email protected], [email protected], [email protected], [email protected])

With the installation completed, you can start weinre by issuing the following command in the terminal window:

weinre

When the server starts, it will indicate that it is running by displaying a message in the terminal window similar to the following:

2013-06-22T17:00:50.564Z weinre: starting server at http://localhost:8080


Note

There are some command-line options you can pass to the weinre server at startup. I chose not to cover them here, but you can find detailed information on the weinre web site at http://goo.gl/DSzqwm.


With the weinre server started, you use a browser-based client application to interact with the server and Cordova client application. Open your browser of choice (I recommend using Safari or Chrome) and point it to the URL shown on the server console when the weinre server started. For my development environment I simply use

http://localhost:8080

The browser will connect to the weinre server, which will display a page similar to the one shown in Figure 5.10. To start the debug client, click on the debug client user interface link shown at the top of the page in Figure 5.10; the browser will open a page similar to what is shown in Figure 5.11.

Image

Figure 5.10 Weinre Debug Server

Image

Figure 5.11 Weinre Debug Client

So far, we’ve done nothing to allow a Cordova application to use the capabilities exposed by weinre, so let’s get to that now. A Cordova application interacts with the weinre server (and debug client) through some JavaScript code that is deployed with the server. To configure a Cordova application to execute this JavaScript code, add the following script tag to the Cordova application’s index.html file:

<script src="http://debug_server:8080/target/target-script-min.js"></script>

You need to replace the debug_server portion of the URL with the correct host name or IP address for the debug server (the system running the weinre server). This makes the application into a weinre debug target and provides the Cordova application with the code needed to upload information to the weinre server as the application runs.

When using weinre with a device simulator, you can usually point the Cordova application to the local weinre server instance using

<script src="http://localhost:8080/target/target-script-min.js"></script>

The Android emulator, however, does not have the ability to connect to host-side resources using localhost, so for the Android emulator you must use the host address http://10.0.2.2 as shown in the following example:

<script src="http://10.0.2.2:8080/target/target-script-min.js"></script>

When using weinre to debug a Cordova application running on a physical device, the device must be able to connect to your debug server. That means that the device must be able to “see” the server on the local network (most likely over a Wi-Fi connection), or the system running the weinre server must have a public-facing IP address. Using a server host name of localhost will not work on a physical device; you must use an actual weinre server host name or IP address that is visible to the device.


Warning

Be sure to remove the weinre script tag from your Cordova application before releasing it into production. The application will likely hang if attempting to connect to a debug server that isn’t available.


After you have added the script tag to the Cordova application’s index.html file, run the application in the simulator or on a device. Nothing special will appear on the device screen; you can’t tell that the weinre debug client is running. However, if you switch to the browser running the weinre debug client, you will see a page similar to the one shown in Figure 5.12. As soon as I start the Cordova application, as long as it can connect to the weinre server, the debug client page will update and display the content shown in the figure.

Image

Figure 5.12 Weinre Debug Client with an Application Activated

The debug client provides the means to view and optionally manipulate many of the page elements and other aspects of your application’s web content.

At this point, the different buttons across the top of the debug client are available to provide you with information about the debug target. For example, in Figure 5.13 you see the contents of the Elements page; it shows you the current HTML5 content running within the debug target.

Image

Figure 5.13 Weinre Debug Client Elements Area

One of the cool features of weinre is that as you highlight the different code sections shown in Figure 5.13, weinre will highlight the corresponding content within the web application. This allows you to see what part of your application’s UI is affected by the code you’re highlighting. So, for the Hello World #3 application shown in Figure 5.13, since I’m highlighting the content div tag, in the debug target you will see that section of the page highlighted as shown in Figure 5.14. The application I’m demonstrating here is the sample application from Chapter 15, “Cordova Development End to End.” The highlighted content area is the area around the compass graphic shown in Figure 5.14.

Image

Figure 5.14 Weinre Target Highlighting HTML Content

You can’t debug the application’s JavaScript code using weinre, but you can edit the content and markup of the application as it runs. In Figure 5.15, you can see that I’ve edited the text displayed in the header of the application. Any changes I make to the page markup or content will be immediately reflected in the running application.

Image

Figure 5.15 Changing Page Content in the Weinre Debug Client

Additionally, on the right side of the figure is a style browser; you can double-click any of the CSS properties and change their values. This allows you to play around with CSS settings in order to get the application looking exactly as you want it to look using a real device (or at least a simulator) in real time.

You can use the Console tab to monitor the application’s console output as shown in Figure 5.16. This is where you will be able to view the content generated by calls to console.log, console.error, and console.warn described earlier in this chapter.

Image

Figure 5.16 Monitoring Console Output in the Weinre Debug Client

Using the debug client, you can access the following content areas:

Image Elements: the HTML, CSS, and JavaScript code for the application

Image Resources: local resources used by the application such as databases, local storage, and session storage

Image Network: information about requests made using XMLHTTPRequests (XHR)

Image Timeline: events that occur within the target application

Image Console: information written to the console using the console object described earlier in the chapter

The available documentation for weinre is pretty light, but since the project’s capabilities are based upon the Google Chrome Developer Tools, you can find additional information on the Google Chrome web site at http://goo.gl/7f6mf1.

The weinre team refers developers who need to step through their JavaScript code in a remote debugger to Aardwolf (http://lexandera.com/aardwolf/), but I’ve not used that tool as it’s currently considered experimental code.

Ripple Emulator

The Ripple Emulator (now called Apache Ripple—http://ripple.incubator.apache.org/) is a tool you can use to help with the initial testing of your Cordova application. Ripple is a browser-based emulator that can be used to emulate several different systems.

Originally created by Tiny Hippos, which was then acquired by BlackBerry, Ripple is now an incubator project at Apache with independent developers working on it. The problem with Ripple is that it seems to be ignored for long stretches of time. As you’ll be able to see in the screen shots in this section, it’s in beta and has been in beta for a very long time (almost three years now by my counting). Typically, Ripple is way behind on its Cordova support—supporting Cordova 3.0 when Cordova 3.6 was just released, for example. Because of those limitations, I’m not going to go into too much detail about how Ripple works. If you like what you see, install it and play around with it to see what it can do.

What’s interesting is that Ripple has started showing up in several Cordova development tools. The Intel XDK uses it as well as the Microsoft hybrid toolkit. Perhaps it will get some attention going forward.

Ripple emulates the execution of many of the Cordova APIs within the browser container. You can use Ripple for quick testing of Cordova application features and UI during development, then switch to packaging/building Cordova applications and testing them on actual devices or device simulators for more thorough testing. Keep in mind, though, that Ripple is not designed to replace testing on real devices or simulators.

Ripple doesn’t provide access to application internals as weinre does. You can learn more about Ripple’s capabilities at http://ripple.incubator.apache.org.

The emulator uses Google Chrome, so you will need to install Chrome from www.google.com/chrome before you begin.

The current iteration of Ripple is Node based, so you install the package using NPM. On a Windows system, open a terminal window, then install Ripple using

npm install -g ripple-emulator

For Macintosh OS X and Linux, install Ripple using

sudo npm install -g ripple-emulator

NPM will churn for a little while, then display the installation results in the terminal window:

C:UsersjwargoAppDataRoaming pm ipple -> C:UsersjwargoAppDataRoaming p
m ode_modules ipple-emulatorin ipple
[email protected] C:UsersjwargoAppDataRoaming pm ode_modules ipple-e
mulator
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected] ([email protected], [email protected], [email protected], cookie-signat
[email protected], [email protected], [email protected], [email protected], [email protected], send
@0.1.0, [email protected], [email protected])

At this point, Ripple is installed and ready to go. To use the emulator, in the terminal window navigate to a Cordova application project and issue the following command:

ripple emulate

Ripple will launch Chrome and launch the Cordova application within the emulator as shown in Figure 5.17. Wrapped around the simulated smartphone are properties panes that can be used to configure options and status for the simulated smartphone such as simulated device screen resolution, accelerometer, network, geolocation, and more.

Image

Figure 5.17 Ripple Emulator Running a Cordova Application

You can click on each of the tabs to expand the options for the tab and make changes to the simulated device’s configuration. At this point, you would simply click around within the simulated smartphone screen and interact with the options presented within your application. When you find a problem or a change you want to make within the Cordova application, simply return to your HTML editor, make the necessary changes, write the changes to disk, then reload the page in the Chrome browser to continue with testing.

When Ripple encounters a problem, it will display an error page like the one shown in Figure 5.18. Remember, this is a very old piece of beta software, so this may happen from time to time. You can click Wait and see what happens, or you can reset Ripple and try again. Simply reload the page in the browser to eliminate many problems.

Image

Figure 5.18 Ripple Error Page

PhoneGap Developer App

A recent addition to the suite of testing tools available to Cordova (actually PhoneGap in this case) developers is the PhoneGap Developer app. The application is a free application, available in the Android, iOS, and Windows app stores today, that provides developers with a quick and easy way to test their applications on mobile devices. You can see an example of the app’s Google Play app store entry in Figure 5.19.

Image

Figure 5.19 PhoneGap Developer App in the Google Play Store

The application is essentially a PhoneGap application with all of the PhoneGap plugins added and some extra code required to open an AJAX connection to the local server to retrieve and load web application content from the server. The application also sends some information back to the server as you’ll see in a little while.

The way this is works is that you install the application on one or more mobile devices, then create a local PhoneGap application project and use the PhoneGap CLI’s serve command to serve the particular application to the mobile devices running the PhoneGap Developer app. Figure 5.20 shows the results of issuing the serve command, in this case serving a PhoneGap application I’ve created in a folder called test.

Image

Figure 5.20 PhoneGap Server Started

The terminal window shown in Figure 5.20 shows you the IP address (192.168.1.29) and port number (3000) the application is being served from. With that information, you can open the PhoneGap Developer app and populate the server address as shown in Figure 5.21.

Image

Figure 5.21 PhoneGap Developer App Running on an Android Device

At this point, the web application you’ve created will be downloaded from the server and launched within the PhoneGap Developer app. You can interact with the application as needed to verify that it is operating correctly. When you make changes to the local mobile application, the PhoneGap Developer app will automatically detect the changes, update itself, and reload the app.

This provides you with an easy way to iterate through the develop and test process—completely eliminating the time you’d normally waste waiting for a prepare, build, and deploy to be completed by the Cordova CLI.

Remember, though, that the PhoneGap Developer app doesn’t provide you with insight into the web application running within the application as weinre does. Console entries, however, are pushed to the server, and you can view them on the console as shown in Figure 5.22. So, if you’ve identified a problem with the application, you can use the console object to send information to the server console to help you troubleshoot the application.

Image

Figure 5.22 PhoneGap Server Console


Warning

The system serving the mobile application must be visible to the mobile devices running the PhoneGap Developer app. In most cases, the system running the PhoneGap serve command won’t be on the public Internet, so cellular-only devices won’t be able to access the server. Any mobile devices running the PhoneGap Developer app will need to be on the same network as the server—most likely connected to a Wi-Fi network that is used by the server or connects to a wired network used by the server.


GapDebug

Another recent entry into the Cordova debugging tools category is GapDebug (http://goo.gl/rsWWrj) from Genuitec. GapDebug is a Chrome-based debugging tool similar to what’s available with weinre, Google Chrome (described in Chapter 7), and Apple Safari (described in Chapter 9, “iOS Development with Cordova”). Unlike weinre, it requires that a physical device be connected to the development system via a USB cable. I could not find information about what mobile device platforms GapDebug supports. I know it supports Android and iOS, but I do not know if support for other devices is planned.

The tool is pretty new and is still in beta as I write this, so I’m not going to go too deeply into how it works as how it works is still being decided. The tool’s web site says, “GapDebug will always be free for local debugging,” so I assume there will be some sort of commercial offering available someday.

On iOS devices, GapDebug makes use of the remote Web Inspector capabilities of the device. Before you can debug applications, you must first enable the Web Inspector. To do this, open the iOS Settings application, select Safari, then at the very bottom of the Settings page select Advanced. Finally, enable the Web Inspector switch as shown in Figure 5.23.

Image

Figure 5.23 Enabling Web Inspector on iOS

GapDebug has an installer for Microsoft Windows and Macintosh OS X—simply go to the web site, then download and install the correct version for your development workstation OS. It uses Google Chrome, so you’ll need to download and install the Google Chrome browser (www.google.com/chrome) as well.

After you install GabDebug, you can launch it using the application shortcut created by the installer. It will open Chrome and display a page similar to what is shown in Figure 5.24.

Image

Figure 5.24 GapDebug Startup Page

You can’t do anything here yet because GapDebug doesn’t see any devices connected to the computer. When you connect one or more devices, the page will update and show a list of available devices in the left pane as shown in Figure 5.25.

Image

Figure 5.25 GapDebug Page with an Application Open

After you launch a “debug-enabled” Cordova application on one of the connected devices, you can click on the application in the left pane and GapDebug will open the application in the right pane, allowing you to interact with the application running on the device.


Note

I’m not really sure what the GapDebug team means by “debug-enabled.” My iOS applications appeared automatically in the window, and for Android there was supposed to be a special setting for enabling GapDebug debug mode in an app, but I couldn’t make it work and in the forums somebody said it was no longer necessary.


GapDebug highlights HTML content in the web application as weinre does. In Figure 5.25 I’ve highlighted one of the paragraph tags in the app; when you look at the application running on the device (shown in Figure 5.26), you can see the content highlighted on the screen. This shows you what part of the application’s UI is affected by the code you’re highlighting. Example 11.1 is one of the example applications from my Apache Cordova API Cookbook (www.cordovacookbook.com).

Image

Figure 5.26 GapDebug Highlighting Web Application Content On-Device

Figure 5.27 shows an example of a capability of GapDebug that allows you to set breakpoints in your JavaScript code, then step through the code as it executes just like traditional debugging tools. This is something that you cannot currently do using weinre. In my testing, setting breakpoints and working closely with an application’s JavaScript code seems to work only when the application’s JavaScript code is its own file rather than being embedded within a page’s HTML. I didn’t expect it to work that way, so I hope this is something that will be fixed before the product is released.

Image

Figure 5.27 Setting Breakpoints in an Application’s JavaScript Code

And finally, always important for the type of applications I write, GapDebug gives you the ability to view an application’s console output as shown in Figure 5.28. You can filter the console messages, see only debug or warning messages, and clear the log from the interface GapDebug provides.

Image

Figure 5.28 Viewing an Application’s Console Output in GapDebug

GapDebug is an interesting tool, and a lot of Cordova developers seem to be taking a look at it. There’s a lot more you can do with it than I’ve shown here; it really simplifies Cordova debugging.

Wrap-Up

By now you should have a pretty good idea of how to build and debug Cordova applications. This chapter highlighted a bit about the development process, then showed you how to test and debug your Cordova applications using some tools that apply across multiple mobile device platforms.

In the next chapter, I’ll show you how to add some automation to the Cordova CLI.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset