Skip to content

Latest commit

 

History

History
682 lines (455 loc) · 57.5 KB

ch14_hybrid.asciidoc

File metadata and controls

682 lines (455 loc) · 57.5 KB

Hybrid Mobile Applications

The word hybrid means something of mixed origin or composition. In the realm of mobile Web applications such a mix consists of the code written in HTML5, which access the APIs written in native languages. If an organization doesn’t want or can’t hire separate teams of software developers (e.g Objective-C developers for iPhone, Java for Android, C# for Windows Phone) there is a way to have one team of developers having HTML/JavaScript skills that will develop applications having the same code deployed on various mobile devices packaged as native applications. Let’s do a quick comparison of native, Web and hybrid mobile applications.

Native Applications

We call a mobile application native if it was written not in HTML/JavaScript, but in a programming language recommended for devices of this mobile platform. The manufacturer of mobile devices releases an SDK and describes a process of creating native applications. Such SDK provides an API for accessing all components (both hardware and software) of the mobile device such as phone, contact list, camera, microphone and others. Such SDKs include UI components that have a native look and feel, so applications developed by third parties look the same as those developed by the respective device manufacturer.

Native applications can seamlessly communicate with each other. They can use all available hardware and software components of the device to create convenient workflows that people quickly get accustomed too. For example, a person can take a picture with her mobile phone, which can figure out the current geographical location and allow to share the photo with other people from her Contacts list. To support such functionality a native application has to access the camera of the mobile device, use GPS to discover the device coordinates, and access the Contacts application.

If you are in the business of writing mobile flight simulators or games that heavily rely on graphics (not a Sudoku type of games) - select a programming language that can use the device hardware (e.g. graphic accelerators) to its fullest and works as fast as possible on this device. Faster applications use less battery power too.

For native applications, a device manufacturer usually offers an application store, which serves as an online market place where people would shop for applications. Apple has the App Store for iOS and MAC OS X applications. Google has Google Play market for Android applications. BlackBerry World is a store where you can find applications for mobile devices manufactured by RIM. Microsoft has their store too.

There are more application stores available, and having a one stop shop is a great way for distributing consumer-oriented applications. For enterprise applications having a public distribution channel may be less important, but enterprises still need a way to publish mobile applications for private use. Apple has iOS Developer Enterprise Program. For Android applications, there is a Google Play Private Channel for internal distribution channels. Microsoft has their process for business applications too.

Note
HTML5 stack is not the only way to develop Hybrid applications using the same language for different mobile platforms. With Xamarin you can develop applications in C# for iOS, Android and Windows Phone.

Native vs. Web Applications

Both Web and native applications have their pros and cons. The latter are usually faster than Web applications. Let’s go through some of the examples of native mobile business applications that exist today.

Bank of America, Chase and other major banks have native mobile applications that allow you to deposit a check by taking a photo of its the front and back sides and entering the amount. At the time of this writing they support iPhones, Android, Windows phones, and iPads.

The Near Field Communication (NFC) technology allows NFC-enabled devices communicate with each other in close distance using radio frequencies. NFC can be used for payments (no need to enter passwords) and data sharing (contacts, photos, et al.) Proliferation of NFC in banking will seriously hurt the credit card industry. A number of smartphones already support NFC technology (see http://www.nfcworld.com/nfc-phones-list). Add one of the existing fingerprint biometrics solutions, and your mobile phone becomes your wallet.

While native applications have full access to all APIs of the mobile device (e.g. contacts, camera, microphone, et al.), they have drawbacks too. For instance, if you want to publish your application at Apple’s App Store you have to submit your application in advance and wait for its approval. If the users run into a crucial bug in your application, even if you fixed the same day, you can’t put a new version in production until it goes through an approval process. Besides this inconvenience there can be other road blocks. For instance, back in 2011 Financial Times (FT) decided to stop using their native iOS application because Apple wouldn’t agree to share the data about FT subscribers with FT - the owner of this application.

Mobile Web applications don’t require any third-party involvement for the distribution. An enterprise can make them available at any time by simple adding a Download button on the corporate Web site. It’s good to have an ability to quickly publish the latest versions Web applications on your own servers without the need to ask for a permission. On the other hand, maintaining the presence on one of the popular app stores is a good channel for getting new customers.

The publisher of New York magazine is heavily investing into their native application for iPad, but the newer version of their Web application is as engaging as its native pier. If you want a Web application to be discoverable and visible by search engines, Web applications are definitely better than the native ones.

Hybrid Applications

Hybrid applications promise you to have the best of both worlds. Develop a Web application in HTML/JavaScript, but access the native API of the mobile device via third-party solutions such as PhoneGap from Adobe or Titanium from Appcelerator. Let’s see what tools are available for creating hybrids.

Cordova is a library (and a build tool) that serves as a bridge between JavaScript and native API. Cordova started from the code donated by Adobe to Apache Software Foundation. Cordova is an open source platform created for building mobile applications with HTML5, but packaged as native ones. PhoneGap is a brand own by Adobe. Besides the Cordova library it offers developers a remote server, where they can package their applications for various mobile platforms. If the role of Cordova library in the PhoneGap product is not clear to you, think of a similar situation when the same software library is used in different products. For example, the rendering engine Webkit, is used in Chrome and Safari browsers. Figure PhoneGap, Cordova and a Web Application illustrates the interaction of PhoneGap, Cordova, and a Web application.

fig 14 01
Figure 1. PhoneGap, Cordova and a Web Application

PhoneGap includes APIs, code generator, and a workflow for creating native application containers for Web applications written in HTML5 (with or without JavaScript frameworks). PhoneGap also allows making JavaScript calls for accessing native API offered by the mobile OS.

PhoneGap Build is a cloud service, where you upload your HTML/JavaScript/CSS code for packaging it for multiple mobile platforms. PhoneGap Build creates several native applications - one per mobile platform. Each application is a wrapper with embedded chrome-less Web browser ( a.k.a. Web View) that looks native to the mobile OS, and has access to various native APIs. Refer to PhoneGap documentation to see what APIs are supported on each mobile platform. The native wrapper serves as a messaging bus between the external native API and HTML-based applications running inside the Web view.

For iOS applications the PhoneGap Build server creates an .ipa file, for deployment on Android devices it generates an .apk file and so on. After that, if you want to submit your application to a public or private application store, follow the procedure that exists for native applications for the selected store. The PhoneGap Build service can package your application for iOS, Android, Windows Phone, Blackberry, and some other platforms.

PhoneGap applications may run slower comparing to the HTML-based applications running in the mobile Web browser, because there is yet another middle man - a Web View. In Android SDK the WebView control is used to embed HTML5 application into a native shell, and the iOS SDK has the UIWebView control for the same purpose. Both of these controls perform slower than respective mobile Web browsers.

Tip
To compare performance of an application that runs in a mobile browser vs WebView or UIWebView control use Google’s V8 Benchmark Suite or SunSpider benchmark utility.

The UI components of the HTML5 framework of your choice may not look native enough. But the main selling point is that PhoneGap (and Cordova) allows you to leverage existing HTML/JavaScript developers' skills for all major mobile platforms, and their bridge to native APIs is easy to learn.

Titanium offers its own set of tools and more extensive API. You’d be writing code in JavaScript (no HTML or CSS) and would need to learn lots of APIs. The compiled and deployed application is a JavaScript code embedded inside Java or Objective-C code plus the JavaScript interpreter plus the platform-specific Titanium API. An important difference between Phonegap and Titanium is that the latter doesn’t use any Web view container for rendering. The business logic written in JavaScript is executed by the embedded interpreter, the final UI components are delivered by native to iOS or Android components from Titanium.

Titanium UI components can be extended to use native OS interface abilities to their fullest. Some components are cross-platform - Titanium has a compatibility layer, while others are platform-specific. But if you want to learn platform-specific components, you might rather invest time in learning to develop the entire application in the native language and APIs. Besides, as new platform are introduced, you’ll depend on the willingness of the Titanium developers to create a new set of components in a timely fashion.

Don’t not expect the top performance from the old Rhino JavaScript engine, which is used by Titanium for Android and Blackberry applications. Oracle has a new JavaScript engine called Nashorn, but it’s available only for Java 8, which doesn’t run on Android, and won’t run there in the foreseeable future. Nashorn is as fast as Google’s V8, but Rhino is slower. Does it mean that Titanium applications on Android and Blackberry will always run slower? This seems to be the case unless Oracle and Google will find a way to stop their quarrels around Java.

The learning curve of the Titanium API is steeper (they have over 5000 APIs) than with PhoneGap. At the time of this writing, Titanium supports iOS, Android, and older versions of Blackberry devices. At the time of this writing they are looking into supporting Windows phones too.

Note
PhoneGap and Titanium are not the only solutions that allow building hybrid applications using HTML5. The framework Kendo UI Mobile can build hybrid applications for iOS, Android, Blackberry, and Window Phone 8. The Mobile Conduit API allows to build cross-platform mobile application with HTML5. Convertigo Mobilizer is a cross-platform enterprise mashup environment that incorporates PhoneGap and Sencha Touch for building mobile applications. IBM Woklight offers to enterprises a client/server/cloud to enterprises develop, test, run and manage HTML5, hybrid and native mobile applications.

The Bottom Line

If a particular enterprise application is intended only for the internal use by people carrying a limited variety of mobile devices, and if making business users productive is your main goal - develop native applications. Start with developing and deploying the first application for the pilot mobile OS (typically for the latest iOS or Android OS), and then gradually add support for more platforms, budget permitting. If you are planning to develop a Web application with a relatively simple UI and have to support a wide variety of unknown consumer devices (e.g. you want to enable people to donate from any device) - develop an HTML5 Web application.

Consider developing a hybrid application for anything in between, and in this chapter we’ll show you how to access the camera of the mobile device with PhoneGap framework. Such functionality can be pretty useful for our Save The Child application as kids who received donations may want to share their success stories and publish their photos after being cured.

Intro to the PhoneGap Workflows

In this section you’ll go through the entire process of building a PhoneGap application. PhoneGap 3.0 offers two major workflows. Each of them allows you to build a mobile application, but the main difference is where you build it - either locally or remotely. Here they are:

  1. Install all required mobile SDKs and tools for the mobile platforms you want to develop for (e.g. iOS and Android), generate the initial project using the Command Line Interface (CLI), write your HTML5 application code, build it locally, and test the application using IDE, simulators and physical devices.

  2. Don’t install any mobile SDK and tools. Just generate the initial project using CLI, add the application code, zip up the www folder and upload it to Adobe PhoneGap Build server, which will build the application for all supported mobile platforms. Then download and and test the application on physical devices.

The second workflow requires running a trivial install of PhoneGap and then just let the Adobe’s Build PhoneGap server do the build for various mobile platforms. The first workflow is more involved, and we’ll illustrate it by showing how to use the local SDKs for iOS deployment.

Note
For some platforms PhoneGap supports only local builds (e.g. BlackBerry 10, Windows Phone 8), while builds for WebOS and Symbian can only be done remotely.

In any case you’ll need to install the PhoneGap software according to the instructions from the command-line interface documentation. Start with installing Node.js, which will also install its package manager npm used for installing Cordova (and PhoneGap library). We’re developing on MAC OS X, and here’s the command that will install PhoneGap:

sudo npm install -g phonegap

The above command installs the JavaScript file phonegap in /usr/local/bin and the Cordova library with supporting files in the /usr/local/lib/node_modules/phonegap - Figure PhoneGap 3.0 Installed shows the snapshot of some of the files and directories that come with PhoneGap. We’ve highlighted the create.js script, which will be used for generating Hello World and Save The Child projects.

fig 14 02
Figure 2. PhoneGap 3.0 Installed

In this chapter we’ll be developing a sample application for the iOS platform to illustrate the most involved deployment-deployment cycle. It requires Xcode IDE, which is available at Apple’s App Store at no charge. After installing Xcode open its menu Preferences and install Command Line Tools (CLT) from the Downloads panel. By default, Xcode comes with the latest iOS simulator (it’s version 6.1 at the time of this writing).

One More Hello World

The time has come for a PhoneGap version of Hello World. We are going to generate the initial project using CLI as described in the same document we used for installing PhoneGap in the section titled "Create the App". We’ll be running the phonegap script:

sudo phonegap create HelloWorld com.example.hello "Hello World"

After generating the Hello World code with the phonegap create command, you’ll see the files and directories as on Figure CLI-generated project Hello World.

fig 14 03
Figure 3. CLI-generated project Hello World
Note
If you’ll be using the create command exactly as it shown in the documentation (i.e. phonegap create HelloWorld com.example.hello "Hello World"), keep in mind that in case of iOS you’ll need to create a certificate, which has to be valid for applications packages located under com.example. For more details see the sidebar "Testing Application on iOS Devices" later in this chapter.

The content of the generated index.html is shown next. It includes several meta tags instructing the browser to use the entire screen of the mobile device without allowing scaling with user’s gestures. Then it includes a couple of JavaScript files in the`<script>` tags.

<!DOCTYPE html>
<html>
 <head>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
     <meta name = "format-detection" content = "telephone=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>Hello Cordova</title>
 </head>
 <body>
     <div class="app">
         <h1>Apache Cordova</h1>
         <div id="deviceready">
             <p class="status pending blink">Connecting to Device</p>
             <p class="status complete blink hide">Device is Ready</p>
         </div>
     </div>
     <script type="text/javascript" src="phonegap.js"></script>
     <script type="text/javascript" src="js/index.js"></script>
     <script type="text/javascript">
         app.initialize();
     </script>
 </body>
</html>

This HTML file includes the code to load the phonegap.js library and the initialization code from index.js.Then it calls app.initialize(). But if you look at CLI-generated project Hello World the file phonegap.js is missing. The CLI tool will add it to the project during the next phase of code generation when you’ll run the command phonegap platform add to add specific mobile platforms to your project. Let’s look at the code of the index.js.

var app = {
  initialize: function() {                   // (1)
      this.bind();
  },

  bind: function() {
    document.addEventListener('deviceready',   // (2)
               this.deviceready, false);
  },

  deviceready: function() {

    app.report('deviceready');
  },

  report: function(id) {                        //  (3)

      console.log("report:" + id);

      document.querySelector('#' + id + ' .pending').className += ' hide';
      var completeElem = document.querySelector('#' + id + ' .complete');
      completeElem.className = completeElem.className.split('hide').join('');
  }
};
  1. This function is being called when all scripts are loaded in index.html.

  2. The mobile OS sends the deviceready event to the PhoneGap application when it’s ready to invoke native APIs.

  3. The function report() is called from the deviceready event handler. It hides the text .pending <p> and shows the .complete <p> in index.html. Technically, split('hide') followed by join('') perform the removal of the word hide.

It wouldn’t be too difficult to prepare such simple HTML and JavaScript files manually, but we prefer using code generators - they are faster and less error prone.

Prerequisites for Local Builds

If you are planning to build your application locally, install the supporting files for the required platforms. For example, you can run the following commands from the command window (switch to the HelloWorld directory) to request the builds for iOS, Android, and Blackberry:

phonegap install ios

phonegap install android

Note
The first command will run fine, because we have Xcode installed. The second command will fail until you install the latest Android SDK as described in the sidebar.

After running the above commands, the initially empty directory platforms will be filled with additional sub-directories specific to each platform. Technically, these commands generate separate Hello World projects - one per platform. Each of them will have its own www directory with index.html and phonegap.js that was missing during the initial project generation. Don’t make any modifications in these www folders as they will be regenerated each time when the install or run command are run. Make the required modification in the root www folder.

You can see on Figure CLI-generated project for iOS platform the content of the ios folder that was generated as a result of executing command phonegap install ios.

fig 14 04
Figure 4. CLI-generated project for iOS platform

Double-click on the file Hello_World.xcodeproj, and Xcode will open it as a project. Press the button Run on the top left corner of the toolbar to compile the project and start in the iOS simulator (see Figure Running Hello World in XCode). Note the "Device is ready" text from index.html (as per index.css this text is blinking and is shown in the upper case).

fig 14 04 1
Figure 5. Running Hello World in XCode

The description of the workflow with the Build Phonegap server will follow.

Testing Applications on iOS Devices

If you want to test your application not in the simulator, but on the physical iOS device, it has to be connected to your Mac computer, enabled for deployment and recognized by Apple. Details on provisioning your devices for development are described in the online iOS Developer Library. If you prefer shorter instructions, here’s what worked for us:

  1. Open a Keychain Access application on your Mac computer and create a certificate request using the menus Keychain Access | Certificate Assistant | Request a Certificate from Certificate Authority. This will create a file with the name extension .certSigningRequest.

  2. Log on to Member Center at developer.apple.com and create a certificate in there for iOS Development specifying the wildcard (an asterisk) in the Bulk name unless you want to restrict this certificate to be used only with application that start with a certain prefix. During this step you’ll need to upload the .certSigningRequest file created in the previous step.

  3. After this certificate is created, download this file (its name ends with .cer), and double-click on it to open in your local keychain. Find it in the list of certificates and expand it - it should include the private key.

  4. Remain in the Member Center, and create a unique application ID.

  5. Finally, in the same Member Center create a Provisioning Profile.

  6. In Xcode, open the menu Window | Organizer, go to Provisioning profiles window, and refresh it. You should see the newly created provisioning profile marked with a green bullet. A physical file with the name extension .mobileprovision correspond to this profile.

  7. Select your iOS device in the active scheme dropdown on top left and run your Hello World or other project on the connected device.

Tip
Read Apple’s App Distribution Guide to learn how to distribute your iOS applications.
Installing more local SDKs

As we stated earlier, you don’t have to install SDK’s locally, but if you decided to do so, consult with instructions by the respective mobile platform vendor. For example, Blackberry developers can download their WebWorks SDK at developer.blackberry.com/html5/download as well as Blackberry 10 Simulator.If you haven’t downloaded the Ripple Emulator (see Chapter 12) you can get it there too.

Instructions for installing the Windows Phone SDK are available at the Windows Phone Dev Center.

To get Android SDK, go to android.com/sdk. We are going to do a simple install by pressing the button "Download the SDK ADT Bundle for Mac", which will download and install Eclipse IDE with ADT plugin, Android SDK tools, Android Platform tools, and Android platform. But if you already have Eclipse IDE and prefer to install and configure required tooling manually, follow the instructions published on this Web site under the section "Use an Existing IDE".

After downloading the bundle, unzip this file, and it’ll create a folder with two subfolders: sdk and eclipse. Start Eclipse IDE from eclipse folder accepting the location of the default workspace. Press the little plus-sign on the top toolbar and open perspective DDMS. There you can use Android emulator while developing Android applications.

Using Adobe PhoneGap Build Service

Instead of installing multiple SDKs for different platforms you can use the cloud service Adobe PhoneGap Build, which already has installed and configured all supported SDK’s and will do a build of your application for different platforms.

Visit build.phonegap.com and sign in with your Adobe or GitHub ID. If your project resides on GitHub, copy its URL to the text field shown on Figure Submitting Application to PhoneGap Build Server. The other way to do a build is to compress your project’s www directory and upload this zip file there.

Note
Starting from PhoneGap 3.0 all code modifications are done in the main www folder of your project. During local rebuilds all the changes get automatically replicated to each installed platfotm’s www folder.
fig 14 04 2
Figure 6. Submitting Application to PhoneGap Build Server

Before zipping up the Hello World’s www directory, open and modify the file config.xml. The generated XML contains a lot of non-related to iOS entries. All of the lines that contain the words android or blackberry should be removed.

<?xml version='1.0' encoding='utf-8'?>
<widget id="com.example.hello" version="2.0.0"
        xmlns="http://www.w3.org/ns/widgets"
        xmlns:cdv="http://cordova.apache.org/ns/1.0">

    <name>Hello World</name>

    <description>
        A sample Apache Cordova application that responds to the deviceready event.
    </description>

    <author email="[email protected]" href="http://cordova.io">
        Apache Cordova Team
    </author>

    <icon height="512" src="res/icon/cordova_512.png" width="512" />
    <icon cdv:platform="ios" height="144" src="res/icon/cordova_ios_144.png" width="144" />
    <cdv:splash cdv:platform="ios" height="748" src="res/screen/ipad_landscape.png" width="1024" />
    <cdv:splash cdv:platform="ios" height="1004" src="res/screen/ipad_portrait.png" width="768" />
    <cdv:splash cdv:platform="ios" height="1496" src="res/screen/ipad_retina_landscape.png" width="2048" />
    <cdv:splash cdv:platform="ios" height="2008" src="res/screen/ipad_retina_portrait.png" width="1536" />
    <cdv:splash cdv:platform="ios" height="320" src="res/screen/iphone_landscape.png" width="480" />
    <cdv:splash cdv:platform="ios" height="480" src="res/screen/iphone_portrait.png" width="320" />
    <cdv:splash cdv:platform="ios" height="640" src="res/screen/iphone_retina_landscape.png" width="960" />
    <cdv:splash cdv:platform="ios" height="960" src="res/screen/iphone_retina_portrait.png" width="640" />

    <feature name="http://api.phonegap.com/1.0/device" />

    <preference name="phonegap-version" value="2.9.0" />
    <access origin="*" />
</widget>

Specify the latest supported PhoneGap version in the "phonegap-version" attribute. The online document Using config.xml has the current information about supported versions and other essential properties. We’ll change the phonegap-version value to 2.9.0, which was the latest supported by PhoneGap Build version at the time of this writing. You’ll see some other entries in config.xml of the Save The Child application.

Now select all the content inside the www folder and compress it into the zip file named helloworld-build.zip. Open the Web browser, go to build.phonegap.com, press the button labeled "Upload a .zip file", and select your local file helloworld-build.zip. When uploading is done, you’ll see a next screen shown at After helloworld-build.zip was uploaded.

fig 14 04 3
Figure 7. After helloworld-build.zip was uploaded

Click on the button "Ready to Build", to start the build for all available platforms. In you did everything right, after watching the wait cursor above each icon, all the builds will successfully complete, and you’ll see a blue line under each button. Figure Two builds failed illustrates the case when the build failed for iOS and BlackBerry platforms (the first and fourth buttons are underlined with in red).

Tip
You can create remote builds on with Adobe PhoneGap Build service from the command line too (phonegap remote build). Read the section "Build Applications Remotely" in the PhoneGap CLI Guide.

Fixing the Blackberry version of the application is not on our agenda. Refer to the Platform Guides documentation that contains specific information on what has to be done to develop and deploy PhoneGap applications for each platform. We’ll just take care of the iOS issue.

fig 14 04 4
Figure 8. Two builds failed

After clicking on the iOS button, it revealed the message in a dropdown box "No key selected". Another error message reads "You must provide the signing key first". The dropdown also offers an option to add the missing key. Selecting this option reveals a panel shown on Figure Uploading certificate and profile.

fig 14 04 5
Figure 9. Uploading certificate and profile

The missing key message actually means that they need the provisioning profile and the certificate discussed in the section "Testing Applications on iOS Devices". The certificate has to be in the P12 format, and you can export it into the .p12 file from the Keychain Access program under MAC OS X. During the export, you’ll assign a password to the certificate that will be required by the PhoneGap Build process. After uploading the .p12 and .mobileprovision files to PhoneGap Build and unlocking the little yellow lock, rebuild the Hello World for iOS and it should run without any errors.

Tip
If you forgot where the .mobileprovision file is located, open Xcode and go to the menu Window | Organize, open the panel Provisioning Profiles under Library, right-click on the profile record and select Reveal in Finder.

To complete the process, deploy the application on your mobile device, which can be done by one of the following methods:

  1. Use the QR Code that was generated specifically for our application - it’s shown on the right side of Figure Two builds failed. Just install a QR Reader program on your device, scan this code and the Hello World application will be installed on your device.

  2. Download the application file from build.phonegap.com to your computer and then copy it onto the mobile device. For example, to get the Android version of the Hello World, just click on the button with Android’s logo and the file HelloWorld-debug.apk will be downloaded to your computer. Copy this file to your Android device and enjoy the application. For the iOS version, click on the button with the iOS logo, which will download the file HelloWorld.ipa on your Mac computer. Double click on this file in Finder, and it’ll bring it into the Application section of iTunes. Synchronize the the content of iTunes with your iOS device, and Hello World will be installed there.

Note
Using the PhoneGap Build service is free as long as you’re building public applications, which have their source code hosted on a publicly accessible HitHub repository. Our Hello World application is considered to be private because we submitted it to PhoneGap Build in a zip file (note the private tab in Figure Submitting Application to PhoneGap Build Server). Only one private application at a time can be built with PhoneGap Build for free. For building multiple private applications you’d need to purchase an inexpensive subscription from Adobe. To replace one application with another, click on its name, then press the buttons Settings and then delete this App.

Phew! This was the longest description of developing and deploying the Hello World application that we’ve ever written! We picked the deployment on the Apple’s devices, which this the most complicated process among all mobile platforms. And we didn’t even cover the process of submission the application in the App Store (you’ll read more about it in the next section)! But developing and deploying an application that have to run natively on multiple platforms is expected to be more complicated that deploying an HTML5 application in a Web browser.

Tip
Instead of using the JavaScript function alert(), display messages using navigator.notification.alert() and PhoneGap will show them using the native message box of the device. The Notification object also supports confirm(), beep(), and vibrate() methods.

Distribution of Mobile Applications

Mobile device manufacturers set their own rules for application distribution. Apple has the most strict rules for the iOS developers.

Apple runs the iOS Developer Program, and if you’re an individual who wants to distribute iOS applications via the App Store, it’ll cost you $99 per year. Higher education institutions that teach iOS development can be enrolled into this program for free. The iOS Developer Enterprise program costs $299 a year.

Besides being able to deploy the application in the App Store, developers can allow their beta-customers to test the application even before they were accepted in the App Store. Individual developers can share their application among up to 100 iOS devices identified by UUID (click on the serial number of your device in iTunes to see it). It’s so-called Ad Hoc distribution.

For example, after the PhoneGap Build service has built the .ipa file for iOS, you can make it available for installation right on the beta-tester’s device using such services as diawi or TestFlight. Upload the .ipa file and its provisioning profile to one of these services and you’ll get the link (a URL) to be given to your testers - the UUID of their devices must be registered with your developer’s profile. To do this, login to your account at developer.apple.com, select the section "Certificates, Identifiers & Profiles", then go to Devices and add the UUID of the iOS device to the existing list of registered devices.

The owners of the enterprise license can distribute their applications right from their own Web sites.

Figure Ad hoc application install from diawi shows the snapshot from the iPhone after the tester clicked on such a link from diawi. Pressing the button Install Application completes the install of the application on your iOS device.

fig 14 05
Figure 10. Ad hoc application install from diawi

Android developers are not restricted in distributing of their application - upload the application’s APK package to your corporate Web site and send the URL to anyone who’s interested. For example, the authors of this book are creating a software for insurance industry, where they offer to download both iOS and Android versions of the application right from their corporate Web site as shown at Figure Distributing mobile applications at surancebay.com.

fig 14 06
Figure 11. Distributing mobile applications at surancebay.com

While simulators and emulators can be very handy, nothing is better than testing on the real devices. There are several models of iPhones that vary by the CPU power and screen resolution. Ensuring that the application performs well on Android devices is a lot more challenging - this market is really fragmented in both hardware and OS use. Android emulators are not as good as the iOS ones. On the other hand, iOS emulator won’t allow you to test the integration with the camera. Such features of the real devices like accelerometer or gyroscope simply can’t be tested with emulators.

Tip
If you’ve architected your hybrid application in a modularized fashion as described in Chapter 7, you’ll get an additional benefit. If the code of one of the loadable modules changes, but the main application shell remains the same, there is no need to resubmit the new version of the application to the App Store or another marketplace. This can be a serious time saver, especially on Apple devices - you eliminate the approval process of each new version of the application.

Save The Child with PhoneGap

To demonstrate how to turn a Web application into a hybrid one, we’ll take the code of the jQuery Mobile version of the Save The Child application from Chapter 12. Initially, we’ll just turn it into a hybrid PhoneGap application as is without adding any native API calls. After that we’ll add to it the ability to work with the photo camera using PhoneGap API and create two builds for iOS and Android platforms. in this exercise we’ll use PhoneGap 3.0.

Note
Usually, PhoneGap is mentioned in the context of building hybrid applications that need to access some native API. But PhoneGap can be used for packaging any HTML5 application as a native one even if it doesn’t use native API.

How to Package Any HTML5 App With PhoneGap

Let’s go through the process of building and deploying the jQuery Mobile version of Save The Child in its existing form without changing even one line of code. Here’s the step by step procedure:

  1. Generate a new PhoneGap project using PhoneGap CLI as we did with Hello World. This time we won’t add any specific mobile SDKs to the project though.

  2. Copy the existing HTML, CSS, JavaScript and other resources from the jQuery Mobile Save The Child application into the directory www of the newly generated PhoneGap project.

  3. Compress the entire content of the www directory into a ZIP file, upload it to PhoneGap Build server and generate the packages for several platforms.

  4. Test the Save The Child application on the Android, iOS or other mobile devices.

Adding Camera Access to Save The Child

Now we’ll add the camera access to the jQuery version of the Save The Child application. The JavaScript code from the jQuery Mobile application. The next code fragment is an extract from the file app-main.js.

The main goal is to use PhoneGap API to access the camera and take the photo. To make this application a bit more useful, we also want to add the functionality to upload the photo image to the server.

Note
As of PhoneGap 3.0, you need to add to your project the plugin supporting camera by running the following command:

For starting the device’s default camera application and taking photos, PhoneGap offers the function navigator.camera.getPicture(), which takes three arguments: the name of the function handler if the photo has been successfully taken, the handler for the error, and the object with the optional parameters describing the image. Details about the camera API are available in the PhoneGap documentation.

var pictureSource;
var destinationType;
var uploadedImagesPage = "http://savesickchid.org/ssc-phonegap/uploaded-images.php";
var photo;

function capturePhoto() {

	navigator.camera.getPicture(
	      onPhotoDataSuccess, onCapturePhotoFail,
	      {
            quality : 49,
            destinationType: destinationType.FILE_URI
          });
}

function onCapturePhotoFail(message) {
	alert('Capture photo failed: ' + message);
}

function onPhotoDataSuccess(imageURL) {
	var smallImage = $('#smallImage');
	photo = imageURL;
	$('#photoUploader').css('display', 'block');
    $('#ssc-photo-app-description').css('display', 'none');
	smallImage.css('display', 'block');
	smallImage.attr("src", imageURL);
	$('#largeImage').attr("src", imageURL);

	$('#uploadPhotoBtn').removeClass('ui-disabled');
	$('#done-msg-holder').css('display', 'none');

}

Depending on the options in the third argument of the getPicture(), the image will be returned as either base64-encoded String, or as in our case, the URI of the file where the image is saved. If the photo was taken successfully, the application will make the #photoUploader button visible.

The above function capturePhoto() should be called when the user taps the button on the application’s screen. Hence we need to register an event listener for this button. Below is a fragment of the onDeviceReady function that registers all required event listeners.

function onDeviceReady() {

    pictureSource = navigator.camera.PictureSourceType;
    destinationType = navigator.camera.DestinationType;

	$(document).on("pageshow", "#Photo-app", function() {

       $('#capturePhotoBtn').on('touchstart', function(e) {
           $(e.currentTarget).addClass('button-active');
       });

       $('#capturePhotoBtn').on('touchend', function(e) {
            $(e.currentTarget).removeClass('button-active');
           capturePhoto();
       });

       $('#uploadPhotoBtn').on('touchstart', function(e) {
            $(e.currentTarget).addClass('button-active');
       });

       $('#uploadPhotoBtn').on('touchend', function(e) {
             $(e.currentTarget).removeClass('button-active');
              uploadPhoto(photo);
       });

       $('#viewGallerylBtn').on('touchend', function() {
               window.open(uploadedImagesPage, '_blank', 'location=no');
        });
	});

If the user clicks on the Upload Photo button, we use the FileTransfer object to send the image to the server side script upload.php for further processing. The code to support file uploading on the client side is shown next.

function uploadPhoto(imageURI) {

	var uploadOptions = new FileUploadOptions();
	uploadOptions.fileKey = "file";
	uploadOptions.fileName = imageURI.substr(imageURI.lastIndexOf('/') + 1);
	uploadOptions.mimeType = "image/jpeg";

	uploadOptions.chunkedMode = false;

	var fileTransfer = new FileTransfer();
	fileTransfer.upload(imageURI, "http://savesickchild.org/ssc-test/upload.php", onUploadSuccess, onUploadFail, uploadOptions);

	var uploadedPercentage = 0;
	var uploadedPercentageMsg = "Uploading...";

	fileTransfer.onprogress = function(progressEvent) {
		if (progressEvent.lengthComputable) {
			uploadedPercentage = Math.floor(progressEvent.loaded / progressEvent.total * 100);
			uploadedPercentageMsg = uploadedPercentage + "% uploaded...";
		} else {
			uploadedPercentageMsg = "Uploading...";
		}
		$.mobile.showPageLoadingMsg("b", uploadedPercentageMsg);
	};
}

function onUploadSuccess(r) {
	$.mobile.hidePageLoadingMsg();

	$('#done-msg-holder').css('display', 'block');
	$('#uploadPhotoBtn').addClass('ui-disabled');
 }

function onUploadFail(error) {
	alert("An error has occurred: Code = " = error.code);
}

The Sever Side Support for Photo Images

To support this application on the server side, we’ve created several PHP scripts. Of course, you can use the programming language of your choice instead of PHP.

The PHP script upload.php shown below performs resizing and saving image files. The files are resized for two purposes: a) to create the thumb for showing image’s preview in a grid b) to create the optimized file with reduced dimensions for showing the image in the mobile browser. This script also moves and saves the thumb, optimal and original files in the corresponding folders on disk.

<?php

function resizeAndSave ($new_width, $new_height, $input, $output, $quality) {

	// Get new dimensions
	// assign variables as if they were an array
	list($width_orig, $height_orig) = getimagesize($input);
	$ratio_orig = $width_orig/$height_orig;

	if ($new_width/$new_height > $ratio_orig) {
	   $new_width = $new_height*$ratio_orig;
	} else {
	   $new_height = $new_width/$ratio_orig;
	}

	//using the GD library
	$original_image = imagecreatefromjpeg($input);

	// Resampling
	$image = imagecreatetruecolor($new_width, $new_height);
	imagecopyresampled($image, $original_image, 0, 0, 0, 0, $new_width, $new_height, $width_orig, $height_orig);

	// Output
	imagejpeg($image, $output, $quality);
	imagedestroy($image);
}

$timestamp = time();
$image_name = $timestamp.'.jpg';
$path_to_original = 'upload/original/'.$image_name;

if(move_uploaded_file($_FILES["file"]["tmp_name"], $path_to_original)) {

	$thumb_width = 200;
	$thumb_height = 200;
	$thumb_output = 'upload/thumbs/'.$image_name;

	$optimum_width = 800;
	$optimum_height = 800;
	$optimum_output = 'upload/optimum/'.$image_name;

	$quality = 90;

	resizeAndSave ($thumb_width, $thumb_height, $path_to_original, $thumb_output, $quality);
	resizeAndSave ($optimum_width, $optimum_height, $path_to_original, $optimum_output, $quality);
}

?>

The following script uploaded-images.php serves the web page with a grid showing thumbs of uploaded images.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title>SSC. Uploaded Images</title>
  <link rel="stylesheet" href="styles.css?<?php echo(time()); ?>">
</head>
<body>
	<ul>
	<?php
	    $thumbs_dir = "upload/thumbs/";
	    //get all image files with a .jpg and .png extension.
	    $thumbs = glob($thumbs_dir."{*.jpg,*.png}", GLOB_BRACE);
		//$images = glob($dir."{*.jpg,*.png}", GLOB_BRACE);
	    foreach($thumbs as $thumb){
			$filename = basename($thumb);
			echo('<li><a href="show-img.php?p='.$filename.'"><img src="'.$thumb.'"></a></li>');
	    }
	?>
  	</ul>
</body>
</html>

The script show-img.php shows a single image in the browser window.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title>SSC. Uploaded Images</title>
  <link rel="stylesheet" href="styles.css?<?php echo(time()); ?>">
</head>
<body>
	<div id="wrapper"><?php $img=$_GET["p"]; echo('<img src="upload/optimum/'.$img.'">'); ?></div>
</body>
</html>

The complete source code of the PhoneGap version of the Save The Child with the camera support is available for download among other book’s code samples.

Summary

Hybrid applications allow you to take the HTML5-based Web application, connect it with the native API of the mobile device and package it as a native application. The selling point of using hybrids is that you can reuse the existing HTML5/JavaScript expertise. In the enterprise setup maintaining bugs in a one-language bug database is a lot more easier than if you had multiple versions of the application written in different languages. Maintaining a single set of images, videos, and CSS files is yet another advantage that lowers both time to market and cost of ownership of the application.

Thorough testing of hybrid applications is a must. With the BYOD policies even the enterprise applications must be tested on a variety of the mobile devices. The development manager and application owners have to agree on the list of mobile devices where your application will be deployed first. This has to be done in writing in the early stages of the project and be as detailed as possible. The statements like "The initial version of the application will run on iOS devices" is not good enough, because the difference between iPhone 3GS and iPhone 5 is huge. The former has 256MB of RAM, 600 Mhz CPU, and 480x320 pixels screen, while the latter champions 1GB of RAM, 3-core A6 CPU at 1.3Ghz, and 1135x640 pixels display.

Hybrid applications not only give the developers and users access to the native capabilities of the mobile devices, but allow distribute your HTML5 application through multiple App Stores or market places offered by device manufacturers.

Enterprise managers are always concerned with the availability of paid technical support. A substantial part of this chapter was about using PhoneGap, and Adobe offers various support packages for purchase.

Make no mistakes though - if you want to create the fastest possible application that looks exactly like other applications on the selected mobile platform, develop it in the native language prescribed by the device manufacturer. Faster applications take less CPU power, which translates to a longer battery life. If you can’t hire experts in each mobile OS going hybrid can be a practical compromise.

Epilogue

Even though this book is about HTML5, the authors would rather work with compiled languages that produce applications running in virtual machines. Such software platforms are more productive for development and more predictable for deployment. While writing this book, we were often arguing about pros and cons of switching to HTML5, and so far we are concerned that the HTML/JavaScript/CSS platform is not overly productive for developing enterprise applications just yet. We live in the era when amateurs feel comfortable creating Web sites and HTML with a little JavaScript inserts provide the flexibility and customization the Microsoft Access and Excel provided in the good old PC times.

Till this day Microsoft Excel is the most popular application among business users in the enterprises. They start Excel locally, it has a local storage that enables work in the occasionally-connected scenarios. Both the data and the code are physically located close to the user’s heart. Microsoft Excel allows the users to have her own little pieces of data and amateurish-but-working-code (a.k.a. formulas) very close and personal. Right on the desktop. No need to ask these IT prima donnas for programming favors. Business users prefer not being dependent on the connectivity or some mysterious servers being slow or down. The most advanced business users even learn how to operate MS Access database to further lessen their dependency from the IT labor force.

But there is only so much you can do with primitive tools. Visual Basic was "JavaScript" of the nineties - it had similar problems, but nevertheless had huge followings. Now the same people are doing JavaScript. If we don’t break this cycle by adopting a common to all browsers VM, we are doomed for going through the generation after generation of underpowered crap. Recently, one of our clients from Wall Street sent us a list of issues to be fixed in an Web application that we were developing using Adobe Flex framework (Flash Player was the VM, where this application ran). One of the requested fixes was "remove a random blink while a widget moves in the window and snaps to another one". We’ve fixed it. You may argue that Flash Player as any browser’s plugins are going away. But the bar set by Flash based enterprise applications is set pretty high. We hope that future enterprise Web applications developed with HTML6 will raise the expectations in the user experience area. The time will come when HTML widgets won’t blink in any of the major browsers.

We wrote this book to help people with understanding of what HTML5 applications are about. But make no mistakes - the world of HTML5 is not a peachy place in the future preached by educated and compassionate scientists, but rather a nasty past that is catching up bringing the mob with it.

It’s past and it’s the future. The chances are slim that any particular vendor will win all or even 80% of the market of the mobile devices. In competitive business, being able to make an application available ONLY to 80% of the market is not good enough, hence the chances that any particular native platform will dominate in the Web developers are slim. HTML5 and related technologies will serve as a common denominator for mobile developers.

Check out one of the trading applications named tradeMonster. It has been developed using HTML5 and uses the same code base for all mobile devices. The desktop version was built using Adobe Flex framework that uses Flash Player as a VM. Yes, they have created native wrappers to offer this application in Apple or Google’s application stores, but it’s still an HTML5 application nevertheless. You can create a paper trading account (no money is involved in trading) and test their application. If you like it, consider using HTML5.

Enterprise IT managers need a cross platform development and deployment platform, which HTML5 is promising to be. Take with a grain of salt all the promises of being 100% cross-platform made by any HTML5 framework vendor. "With our HTML5 framework you won’t need to worry about differences in Web browsers". Yeah, right! HTML5 is not a magic bullet, and don’t expect it to be. But HTML5 is for real and may become the most practical development platform for your organization today.

Unfortunately, developing an application in JavaScript is not overly productive. Some people use CoffeScript or TypeScript to be converted for JavaScript for deployment. We are closely watching the progress with Google’s new programming language called Dart, which is not a production-grade software as of yet. Dart is a compiled language with an elegant and terse syntax, which is easy to understand to anyone who knows Java or C#. Although compiled version of the Dart code requires Dartium VM, which is currently available only in the Chromium browser, Google created dart2js compiler that turns your application code into JavaScript in seconds so it can run in all Web browsers today. Google also offers Dart IDE with debugger and autocomplete features. You can debug the Dart code in Dart Editor while running generated JavaScript in the browser.

Dart’s VM can communicate with JavaScript’s VM, so if you have a portion of your application written in JavaScript, it can peacefully coexist with the Dart code. You can literally have two buttons on the Web page: one written in JavaScript and the other in Dart.

W3C published a document called "Introduction to Web Components", which among other things defines recommendations on how to create custom HTML components. The existing implementation of Web UI package includes a number of UI components and allows defining new custom HTML elements in a declarative way. Here’s an example we borrowed from the Dart Web site:

  <element name="x-click-counter" constructor="CounterComponent" extends="div">
    <template>
      <button on-click="increment()">Click me</button>
      <span>(click count: {{count}})</span>
    </template>
    <script type="application/dart">
      import 'package:web_ui/web_ui.dart';

      class CounterComponent extends WebComponent {
        int count = 0;
        void increment(e) { count++; }
      }
    </script>
  </element>

This code extends the Web UI element div and includes a template, which uses binding. The value of the variable count is bound to <span> and as soon as a counter increases, the Web page immediately reflects its new value without the need to write any other code. The Web UI package will be replaced soon with the Polymer Stack built on top of Web components. In 2014, the popularity of Dart should increase if Google will remain committed to this project. In this case, we’ll send a new proposal to O’Reilly Media for a book titled "Enterprise Web Development with Dart".

Having said that, we’d like you to know that at the time of this writing the popular job search engine Indeed.com reports that HTML5 is the #1 job trend - the fastest growing keyword found in online job postings - ahead of iOS in third place and Adnroid in fourth place. We’ll be happy if our book will help you in mastering HTML5 and finding an interesting and financially rewarding job!

  • [flanagan] David Flanagan. 'Javascript. The Definitive Guide. 6th Edition'. O’Reilly. 2011.