Anatomy of a Cordova Application
Now that you know a little bit about how to create a Cordova application project, it’s time to show you what makes a Cordova application a Cordova application. In this section, I show how to create a Cordova web application that leverages one of the Cordova Core APIs.
To begin, I opened a terminal window and navigated to the folder where I wanted to create the project. Next, I issued the following commands:
cordova create hellocordova1 cd hellocordova1 cordova platform add android ios cordova plugin add org.apache.cordova.device
This created a hellocordova1 project folder, added the Android and iOS platforms to the project, and then added the code for the Cordova Device API. Next, I navigated to the project’s www folder and pasted the code from Listing 1.1 into the project’s existing index.html file.
Listing 1.1 Hello Cordova 1
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <meta name="viewport" id="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" /> <script type="text/javascript" charset="utf-8" src="cordova.js"> </script> <script type="text/javascript" charset="utf-8"> function onBodyLoad() { document.addEventListener("deviceready", onDeviceReady, false); } function onDeviceReady() { var br = "<br />"; //Get the appInfo DOM element var element = document.getElementById('devInfo'); //Replace it with specific information about the device //running the application element.innerHTML = 'Cordova Version: ' + device.cordova + br + 'Operating System: ' + device.platform + br + 'OS Version: ' + device.version + br + 'Device Model: ' + device.model + br + 'Universally Unique Identifier: ' + device.uuid; } </script> </head> <body onload="onBodyLoad()"> <h1>Cordova Information</h1> <p>This is an Apache Cordova application that makes calls to the Cordova Device API.</p> <p id="devInfo">Waiting for Cordova initialization to complete.</p> </body> </html>
The index.html file shown in the listing is like any other HTML page you’ve seen, with some extra elements that enable it to understand how to interact with the Cordova container. The content-type setting is a standard HTML setting and should look the same as it would for any other HTML5 application. Within the <Head> section of the web page are two new entries, meta tags that describe the content type for the application and viewport settings.
The viewport settings shown in the following code tell the embedded web browser rendering the content how much of the available screen real estate should be used for the application and how to scale the content on the screen:
<meta name="viewport" id="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
In this case, the HTML page is configured to use the maximum height and width of the screen (through the width=device-width and height=device-height attributes) and to scale the content at 100% and not allow the user to change that in any way (through the initial-scale=1, maximum-scale=1, and user-scalable=no attributes).
There’s also a new script tag in the code that loads the Cordova JavaScript library:
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
This loads the Cordova API library and makes some Cordova capabilities available to the program.
The JavaScript code in a Cordova application does not have immediate access to any installed Cordova APIs after the web application has loaded. The native Cordova application container must complete its initialization process before it can respond to calls JavaScript made using the Cordova APIs. To accommodate this delay in API availability, a web developer building Cordova applications must instruct the container to notify the web application when the Cordova APIs have completed initialization. Any application processing that requires the use of the APIs should be executed by the application only after it has received notification that the APIs are available.
In the application, this notification is accomplished through the addition of an onload event defined in the page’s body section as shown in the following:
<body onload="onBodyLoad()">
Within the onBodyLoad function, the code registers an event listener that instructs the application to call the onDeviceReady function when the device is ready, when the Cordova application container has finished its initialization routines and fired its deviceready event:
document.addEventListener("deviceready", onDeviceReady, false);
In this example application the onDeviceReady function updates the page rendered on the screen to display all of the available properties exposed by the Cordova Device API (described in Chapter 8) as shown in the following:
//Replace it with specific information about the device //running the application element.innerHTML = 'Cordova Version: ' + device.cordova + br + 'Operating System: ' + device.platform + br + 'OS Version: ' + device.version + br + 'Device Model: ' + device.model + br + 'Universally Unique Identifier: ' + device.uuid;
To run the application on an Android emulator, open a terminal window, navigate to the Cordova project folder, and issue the following command:
cordova emulate android
The default Android emulator will launch and display the application as shown in Figure 1.5.
Figure 1.5 Hello Cordova 1 Running on an Android Emulator
When the application runs on an iOS simulator, it will display a screen similar to what is shown in Figure 1.6.
Figure 1.6 Hello Cordova 1 Running on an iOS Simulator
One of the common questions I get from people first learning Cordova is “Can I use HTML5 or JavaScript framework X with Cordova?” (substituting the name of their favorite HTML5 or JavaScript framework—jQuery Mobile, Sencha Touch, Dojo, and so on—into the question). The answer is unequivocally yes. The Cordova application simply renders whatever web content you pass to it using the native browser web view exposed by the mobile device OS.
As a side project, to help developers easily build more beautiful mobile applications, Adobe created Topcoat (www.topcoat.io). Topcoat is a set of CSS files and open-source fonts that can be used to create fast, themeable, beautiful web sites. In an effort to make the sample applications highlighted in this book prettier, where appropriate I’m going to use Topcoat to apply styling to many of the applications.
So, once I downloaded the Topcoat files, I extracted them and copied over the font and CSS files to my project folder, then updated the application’s HTML to use the Topcoat styling. You can see an updated listing for the example application, now called Hello Cordova 2, in Listing 1.2.
Listing 1.2 Hello Cordova 2
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <meta name="viewport" id="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" /> <link rel="stylesheet" type="text/css" href="css/topcoat-mobile-light.min.css"> <script type="text/javascript" charset="utf-8" src="cordova.js"> </script> <script type="text/javascript" charset="utf-8"> function onBodyLoad() { document.addEventListener("deviceready", onDeviceReady, false); } function makeListItem(textStr) { return '<li class="topcoat-list__item">' + textStr + '</li>'; } function onDeviceReady() { var tmpStr; tmpStr = '<ul class="topcoat-list__container"> <h3 class="topcoat-list__header">Device API Properties</h3>'; tmpStr+= makeListItem('Cordova Version: ' + device.cordova); tmpStr+= makeListItem('Operating System: ' + device.platform); tmpStr+= makeListItem('OS Version: ' + device.version); tmpStr+= makeListItem('Device Model: ' + device.model); tmpStr+= makeListItem('Universally Unique Identifier: ' + device.uuid); tmpStr+= '</ul>'; //Get the appInfo DOM element var element = document.getElementById('devInfo'); //Replace it with specific information about the device running //the application element.innerHTML =tmpStr; } </script> </head> <body onload="onBodyLoad()"> <div class="topcoat-navigation-bar"> <div class="topcoat-navigation-bar__item center full"> <h1 class="topcoat-navigation-bar__title">Hello Cordova #2</h1> </div> </div> <h1>Cordova Information</h1> <p>This is an Apache Cordova application that makes calls to the Cordova Device API.</p> <div class="topcoat-list" id="devInfo"> <h3 class="topcoat-list__header"> Waiting for Cordova to initialize </h3> </div> </body> </html>
I added the application’s title to a title bar, assigning class=“topcoat-navigation-bar”, class=“topcoat-navigation-bar__item center full”, and class=“topcoat-navigation-bar__title” to the elements of the header as shown in the listing. To render the list of Device API properties on the screen, I created an unordered list, with the appropriate class assignment, then applied class=“topcoat-list__item” to each list item. When the modified application runs on an Android emulator, it displays a screen similar to what is shown in Figure 1.7.
Figure 1.7 Hello Cordova 2 Running on an Android Emulator
Notice how much better that looks? To prove it works as well on iOS, when the application runs on an iOS simulator, it displays a screen similar to what is shown in Figure 1.8.
Figure 1.8 Hello Cordova 2 Running on an iOS Simulator