Develop Apache Cordova Applications with HTML5 & JavaScript

In a prior discussion we looked at how to set up a project so that we could develop an Apache Cordova application using HTML5 and JavaScript. In that section we mostly covered how to set up, build, and run the project — which consisted of the same application in the www folder that Apache Crodova bootstraps when you create a new project. In what follows we will look at the approach for actually writing own code for our app and will look at how an app in Apache Cordova gets initialized. We will also look at how we can extend the Apache Cordova platform by using plugins to give ourselves additional features and functionality that will make for an all around better user-experience (UX) for the users of our app.

Now that we have our project set up and all our platforms added all that we have left to do now is create our application by creating what basically amounts to a website that runs HTML and JavaScript in the “www” folder. How should one develop for Apache Cordova? Personally, I would delete all of the boilerplate files and folders and start from scratch. That is what we will do here. Just take a quick note of how things are referenced in the index.html file and do the same for your own files.

In doing this, I have modified the index.html file in the “www” folder to the following…

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
        <meta name="format-detection" content="telephone=no">
        <meta name="msapplication-tap-highlight" content="no">
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
        <link rel="stylesheet" type="text/css" href="css/index.css">
        <title>Cordova Application</title>
    </head>
    <body>
        
        <div id="main">Initializing...</div>
        
        <script type="text/javascript" src="cordova.js"></script>
        <script type="text/javascript" src="js/index.js"></script>
    </body>
</html>

Note: Do not worry about that “cordova.js” reference or the fact that this file is nowhere to be found in our “www” folder. Apache Cordova will utilize this in the proper context when the app runs (so leave it in there).

So as far as the index.html goes, there is nothing too fancy. I have a css file (index.css) and a js file (index.js). That is all you need to get started.

Next, let’s look at our JavaScript in the index.js file. There is really only one thing you need to make note of when you develop Apache Cordova applications in JavaScript. There is a special event that Apache Cordova uses to tell the platform that the everything is loaded and the device you are using is ready to start running JavaScript in your Cordova application. This is what is known as the “deviceready” event. It only fires when you are running an app within a Cordova context (i.e. on a device or an emulator of a device). In a lean version of JavaScript for a cordova application would look like the following (in index.js)…

var app = {
    init: function() {
        document.addEventListener('deviceready', this.main, false);
    },
    main: function() {
        document.getElementById('main').innerText = 'App is ready...'
    }
};

app.init();

Here we are calling the “init” function which will add a listener for the “deviceready” event. When this event fires the “main” function will run, which in this case just changes the inner text of a div element So if we run this using

$ cordova emulate android

or

$ cordova emulate ios

from the root of our project we will see our device boot up, our app launch, and if all goes well we will see the text “App is ready…” so we know that our event is firing.

But it gets kind of annoying to have to fire up the emulator every time we want to test something out or make small changes in doing development. So it would be easier to be able to open the index.html file in the browser. But the problem with this is that the browser does not natively support the “deviceready” event. If you try to open index.html in a browser you see that the text remains as “Initializing…” The “deviceready” event does not get fired by the browser. So to get around this we have to set a flag so that we conditionally check if we are trying to run our app in a browser. So update the code in index.js to the following…

var config = {
    DEV: true    
};

var app = {
    init: function() {
        if(config.DEV) {
            this.main();
        } else {
            document.addEventListener('deviceready', this.main, false);
        }
    },
    main: function() {
        document.getElementById('main').innerText = 'App is ready...'
    }
};

app.init();

Now that we have set a flag in config to check whether we are just intending to run in “dev mode” in the browser, we will just call the main function directly and that will be the place that we kick off our application. We essentially bypass the “deviceready” step.

Now if you run this in the browser, we see that the “App is ready…” text is rendered to the page. If we change the config.DEV flag to “false” and run

$ cordova emulate android

or

$ cordova emulate ios

we can see that our main function is still running to kick off our app.

Even though the “deviceready” event is kind of the official Apache Cordova way of making sure that everything is initialized, if you forget to change the “DEV” flag to “false” and directly call the “main” function while running on a device, things will probably still work.

Splash Screens, Icons, & Using Plugins

Apache Cordova gives you a great framework out of the box to create a mobile app that can run on different platforms (as we have seen). But as great as it is, often there are things that you run into that may not be as easy to implement as they would be if you were creating an app using the native tools and languages. Fortunately, if you run into something that is not natively supported in Apache Cordova, there is a vibrant plugin ecosystem (and community behind it) that has worked to extend the support and functionality of the framework. You may have noted that there was a “plugins” folder in our Apache Cordova project. This is where installed plugins go.

Let’s take a look at a plugin that allows us to display a “splash screen” while our app launches. This is a common feature that you may have seen in many apps. We will use the cordova-plugin-splashscreen plugin. This plugin will allow us to specify paths to images that we will use as our splash screens. Because there are so many different resolutions across iOS and Android phones and tablets, we are going to have to specify a number of different resolutions of images that we will use for our splash screens. It will also allow you to show the Rather than list out what each of these resolutions need to be I have included a sample Apache Cordova project here as a download with some blank images of the sizes that they need to be to support this feature on most (nearly all) modern devices (iPhones, iPads, Android phones, and Android tablets). You can find these in the “res” folder in the “www” directory.

This cordova-plugin-splashscreen plugin will also allow us to specify the images that will be used for the icon of our app that shows up on the user’s home screen when the app gets installed. Up until now, Apache Cordova has just been using its own default image (that little robot looking thingy). But with this plugin we can change the icon, to what we want it to be! Awesome!

To install our plugin we just need to run the following from the root of our Apache Cordova project…

$ cordova plugin add cordova-plugin-splashscreen

If for some reason that does not work for you, you can try running the following

$ cordova plugin add https://github.com/apache/cordova-plugin-splashscreen.git

Once the plugin is installed we can now specify the paths to our splash screens and icons. We will do this in the config.xml that resides in the root of our project. As mentioned prior I have posted a sample Apache Cordova project that is available for download. In that project we can see the config.xml file that looks like the following…

<?xml version='1.0' encoding='utf-8'?>
<widget id="com.sample.sampleapp" version="0.0.1" xmlns="https://w3.org/ns/widgets" xmlns:cdv="https://cordova.apache.org/ns/1.0">
    <name>SampleApp</name>
    <description>
        A sample Apache Cordova application...
    </description>
    <author email="dev@cordova.apache.org" href="https://cordova.io">
        Apache Cordova Team
    </author>
    <content src="index.html" />
    <plugin name="cordova-plugin-whitelist" spec="1" />
    <access origin="*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    <platform name="android">
        <allow-intent href="market:*" />
        <!-- Android Icons -->
        <icon src="www/res/android/icons/ldpi.png" density="ldpi" />
        <icon src="www/res/android/icons/mdpi.png" density="mdpi" />
        <icon src="www/res/android/icons/hdpi.png" density="hdpi" />
        <icon src="www/res/android/icons/xhdpi.png" density="xhdpi" />
        
        <!-- Android Splash Screens -->
        <splash src="www/res/android/screen/splash-land-hdpi.png" density="land-hdpi"/>
        <splash src="www/res/android/screen/splash-land-ldpi.png" density="land-ldpi"/>
        <splash src="www/res/android/screen/splash-land-mdpi.png" density="land-mdpi"/>
        <splash src="www/res/android/screen/splash-land-xhdpi.png" density="land-xhdpi"/>
        <splash src="www/res/android/screen/splash-port-hdpi.png" density="port-hdpi"/>
        <splash src="www/res/android/screen/splash-port-ldpi.png" density="port-ldpi"/>
        <splash src="www/res/android/screen/splash-port-mdpi.png" density="port-mdpi"/>
        <splash src="www/res/android/screen/splash-port-xhdpi.png" density="port-xhdpi"/>   		
    </platform>
    <platform name="ios">
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
        <!-- iOS Icons -->
        <icon src="www/res/ios/icons/icon-60@3x.png" width="180" height="180" />
        <icon src="www/res/ios/icons/icon-57.png" width="57" height="57" />
        <icon src="www/res/ios/icons/icon-57@2x.png" width="114" height="114" />
        <icon src="www/res/ios/icons/icon-60.png" width="60" height="60" />
        <icon src="www/res/ios/icons/icon-60@2x.png" width="120" height="120" />
        <icon src="www/res/ios/icons/icon-76.png" width="76" height="76" />
        <icon src="www/res/ios/icons/icon-76@2x.png" width="152" height="152" />
        <icon src="www/res/ios/icons/icon-40.png" width="40" height="40" />
        <icon src="www/res/ios/icons/icon-40@2x.png" width="80" height="80" />
        <icon src="www/res/ios/icons/icon.png" width="57" height="57" />
        <icon src="www/res/ios/icons/icon@2x.png" width="114" height="114" />
        <icon src="www/res/ios/icons/icon-72.png" width="72" height="72" />
        <icon src="www/res/ios/icons/icon-72@2x.png" width="144" height="144" />
        <icon src="www/res/ios/icons/icon-small.png" width="29" height="29" />
        <icon src="www/res/ios/icons/icon-small@2x.png" width="58" height="58" />
        <icon src="www/res/ios/icons/icon-50.png" width="50" height="50" />
        <icon src="www/res/ios/icons/icon-50@2x.png" width="100" height="100" />
        
        <!-- iOS Splash Screens -->
        <splash src="www/res/ios/screen/Default~iphone.png" width="320" height="480"/>
        <splash src="www/res/ios/screen/Default@2x~iphone.png" width="640" height="960"/>
        <splash src="www/res/ios/screen/Default-Portrait~ipad.png" width="768" height="1024"/>
        <splash src="www/res/ios/screen/Default-Portrait@2x~ipad.png" width="1536" height="2048"/>
        <splash src="www/res/ios/screen/Default-Landscape~ipad.png" width="1024" height="768"/>
        <splash src="www/res/ios/screen/Default-Landscape@2x~ipad.png" width="2048" height="1536"/>
        <splash src="www/res/ios/screen/Default-568h@2x~iphone.png" width="640" height="1136"/>
        <splash src="www/res/ios/screen/Default-667h.png" width="750" height="1334"/>
        <splash src="www/res/ios/screen/Default-736h.png" width="1242" height="2208"/>
        <splash src="www/res/ios/screen/Default-Landscape-736h.png" width="2208" height="1242"/>  		
		
    </platform>
    <preference name="SplashScreen" value="screen" />
    <preference name="SplashScreenDelay" value="4000" />
</widget>

As we can see, we have specified paths to a number of different images of different resolutions. with these settings the cordova-plugin-splashscreen Apache Cordova plugin will automatically figure out which is the best resolution to use depending on the

We can also see that in the <preference> elements down at the bottom we have specified “SplashScreenDelay” preference down at the bottom of the config.xml file. This specifies to show the splash screen for 4 seconds (4000 milliseconds). You can change this value to the one that you prefer.

Now if you run your application with

$ cordova emulate android

or

$ cordova emulate ios

You will see a splash screen displayed before the app launches. It’s blank for now until you bust out your graphic designer skills and create a nice looking one. If you click on the “home” button on the emulator device you can see on the home screen that the icon we have in our project is now used as the app icon. Like with the splash screen, obviously for a production app we would want to make nice looking icons consistent with the theme of our app. But the functionality is there and all you have to do is replace the icons and splash screens in the sample project with your own app branding.

So sample project and try it out. Note: After downloading the project you will need to 1) add the platform(s) that you want to work with with $ cordova platform add and 2) install the splash screen plugin with $ cordova plugin add cordova-plugin-splashscreen.

Summary

Now that we have walked through how to set up some app initialization code from here, everything that you want to do is entirely up to you. There are really no limitations on what you can do here. Apart from the unique “deviceready” event there is nothing special that you need to do to code for Apache Cordova (and even hooking into the “deviceready” event probably isn’t even absolutely essential). You can just create things in the same way that you would if you were going to put this web application on the web and have users run it in their browsers. There is no special magic needed. You can add more CSS files, images, other JavaScript files, or whatever else you want to and start building. You can use popular front-end frameworks like Bootstrap or Foundation. Or, if you prefer, you can import a framework specifically designed for mobile such as jQuery Mobile. You can use popular JavaScript development frameworks like Backbone.js, Ember.js, AngularJS, or React. Ultimately the choice is entirely up to you. I cannot choose for you.

From there, the sky’s the limit. You can do whatever you like to create whatever kind of app you want. But since there are so many different types of applications for so many different purposes, it is ultimately up to you to decide on what technologies you want to use and what is the best way to implement your app. So get out there and develop it up. Until next time, cheers and happy developing!

9bit Studios E-Books

Like this post? How about a share?

Stay Updated with the 9bit Studios Newsletter

0 Responses to Develop Apache Cordova Applications with HTML5 & JavaScript

Leave a Reply