PhoneGap

Migrating to the Cordova CLI

With PhoneGap Build shutting down, many developers are now left trying to find options to continue building their Cordova-based applications. While several new services like Ionic’s Appflow and Monaca Cloud have entered the market as replacements. Their cost might be too much for the independent developer. One of the things that attracted many to use PhoneGap Build was it was included as part of your Creative Cloud subscription. There was even a free version for open-source projects. For those developers who are either resource constrained or want complete control over their build system, they should migrate to using the Cordova CLI and building locally.

There are four general steps we need to take to accomplish this:

  1. Install the Cordova CLI
  2. Install the native build environments
  3. Migrate our existing PhoneGap Build App to use Cordova
  4. Build and Test!

Step 1: Installing the Cordova CLI

The Cordova CLI is a free, open source tool that is actively maintained by many of the former PhoneGap team. It runs on Node.js and is available on NPM. You can learn more about it by visiting their site, https://cordova.apache.org/.

To install the Cordova command-line tool, follow these steps:

1. Download and install Node.js [https://nodejs.org/en/download/]. On installation you should be able to invoke node and npm on your command line.

2. Install the Cordova CLI using npm.

On OS X and Linux use the following command:

$ sudo npm install -g cordova

On OS X and Linux, prefixing the npm command with sudo may be necessary to install this development utility in otherwise restricted directories such as /usr/local/share. If you are using the optional nvm/nave tool or have write access to the install directory, you may be able to omit the sudo prefix. There are more tips available on using npm without sudo, if you desire to do that.

On Windows do the following:

C:\>npm install -g cordova

The -g flag above tells npm to install cordova globally. Otherwise it will be installed in the node_modules subdirectory of the current working directory.

To test the installation, simply run

$ cordova

on the command line with no arguments and it should print help text.

You will probably want to bookmark the Cordova CLI reference page while you are learning the various CLI commands and parameters. This can be found at: https://cordova.apache.org/docs/en/latest/reference/cordova-cli/

Step 2: Install the native build environments

One of the major appeals of PhoneGap Build was not having to install the native build tools for each platform. This was especially true for Android, as it required multiple components to be properly installed. PhoneGap Build also allowed Windows users to compile iOS applications without needing a Macintosh.

Now that you are building locally, your will will need access to a Mac with Xcode installed to create your IPA files. Some options to get around this requirement are to use one of the “Mac in the Cloud” services or instead migrate to one of the PhoneGap Build replacements, or consider deploying your application as Progressive Web App.

Rather than rewrite the instructions outlined by the Apache Cordova team, I will point you to the specific instructions for each platform:

Android Setup

You will be installing the following elements: Java Development Kit (JDK), Gradle, Android Studio and the Android SDKs.

iOS Setup

The iOS installation is basically just installing Xcode on your Macintosh.

Once this is done, we can validate that status of the tools by running a Cordova command to verify the state of them In the command line run the follow:

$ cordova requirements

You will see a report of the status of the various requirements. If something is not installed, you should go back and reinstall it.

Step 3: Migrate your existing PhoneGap Build App

The method I recommend is to migrate your existing PhoneGap Build app is to first start with a new Cordova application. To create a blank Cordova project using the command-line tool, navigate to the directory where you wish to create your project and run

$ cordova create  [ID [NAME ]]

cordova create [ID [NAME [CONFIG]]] [options]

PATH ……………………. Where to create the project
ID ……………………… Reverse-domain-style package name – used in
NAME ……………………. Human readable name

Here is a sample command:

$ cordova create myapp com.mycompany.myteam.myapp MyApp

With the basic application skeleton in place, we need to navigate to the project directory that was just created using the change directory, or CD command:

$ cd myapp

From the project directory, you need to add the platforms for which you want to build your app.

The general command is:

$ cordova platform add

To add the iOS platform

$ cordova platform add ios

To add the Android platform

$ cordova platform add android

These can take a bit to install, so be patient. Although you can install any platform, it does not mean you can compile for that platform.

With all the necessary requirements in place, we can perform our first build by running

$ cordova build

The process will take a bit, but it should generate the artifacts we need.

Since SDKs for Android and iOS come bundled with emulators, we can use them without the additional steps required to deploy them onto an actual device. We can target the emulator by running this command:

$ cordova emulate

The app will be built, the proper emulator launched and the app installed. This can take a bit. You may need to refer to the Cordova documentation to make sure you have the native environment setup correctly and the emulator/simulators configured correctly.

Now that we know we can build and emulate a basic Cordova app, we can move on migrating our actual application. With the platforms installed, let’s take a look at the directory structure that was generated:

config.xml
hooks
node_modules
package-lock.json
package.json
platforms
plugins
www

There are some folders and files that might look familiar, and others that might be new to you. Now we can roll up our sleeves and do the real migration.

In most PhoneGap Build apps, you probably have a single www folder that contains your code, application resources and it’s config.xml file. This is typically the structure that I see:

resources
config.xml
css
img
index.html
js

Go ahead and replace the www folder that was created with the Cordova CLI with the contents of your PhoneGap Build www. Next, we are going to move your resources directory, the one containing your app icons and splash screens and move it to the root directory for the project. The final step will be editing the main config.xml file. By default, the Cordova CLI generates a bare-bones config.xml file, so references to any icons or splash screens are not included.

I recommend following standard directory and file naming structures to reduce possible headaches. In the main config.xml file add the following elements. If you are not targeting that particular platform, feel free to skip it.

<platform name="android">
<allow-intent href="market:*" />
<icon density="ldpi" src="resources/android/icon/drawable-ldpi-icon.png" />
<icon density="mdpi" src="resources/android/icon/drawable-mdpi-icon.png" />
<icon density="hdpi" src="resources/android/icon/drawable-hdpi-icon.png" />
<icon density="xhdpi" src="resources/android/icon/drawable-xhdpi-icon.png" />
<icon density="xxhdpi" src="resources/android/icon/drawable-xxhdpi-icon.png" />
<icon density="xxxhdpi" src="resources/android/icon/drawable-xxxhdpi-icon.png" />
<splash density="land-ldpi" src="resources/android/splash/drawable-land-ldpi-screen.png" />
<splash density="land-mdpi" src="resources/android/splash/drawable-land-mdpi-screen.png" />
<splash density="land-hdpi" src="resources/android/splash/drawable-land-hdpi-screen.png" />
<splash density="land-xhdpi" src="resources/android/splash/drawable-land-xhdpi-screen.png" />
<splash density="land-xxhdpi" src="resources/android/splash/drawable-land-xxhdpi-screen.png" />
<splash density="land-xxxhdpi" src="resources/android/splash/drawable-land-xxxhdpi-screen.png" />
<splash density="port-ldpi" src="resources/android/splash/drawable-port-ldpi-screen.png" />
<splash density="port-mdpi" src="resources/android/splash/drawable-port-mdpi-screen.png" />
<splash density="port-hdpi" src="resources/android/splash/drawable-port-hdpi-screen.png" />
<splash density="port-xhdpi" src="resources/android/splash/drawable-port-xhdpi-screen.png" />
<splash density="port-xxhdpi" src="resources/android/splash/drawable-port-xxhdpi-screen.png" />
<splash density="port-xxxhdpi" src="resources/android/splash/drawable-port-xxxhdpi-screen.png" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
<icon height="57" src="resources/ios/icon/icon.png" width="57" />
<icon height="114" src="resources/ios/icon/icon@2x.png" width="114" />
<icon height="29" src="resources/ios/icon/icon-small.png" width="29" />
<icon height="58" src="resources/ios/icon/icon-small@2x.png" width="58" />
<icon height="87" src="resources/ios/icon/icon-small@3x.png" width="87" />
<icon height="20" src="resources/ios/icon/icon-20.png" width="20" />
<icon height="40" src="resources/ios/icon/icon-20@2x.png" width="40" />
<icon height="60" src="resources/ios/icon/icon-20@3x.png" width="60" />
<icon height="48" src="resources/ios/icon/icon-24@2x.png" width="48" />
<icon height="55" src="resources/ios/icon/icon-27.5@2x.png" width="55" />
<icon height="29" src="resources/ios/icon/icon-29.png" width="29" />
<icon height="58" src="resources/ios/icon/icon-29@2x.png" width="58" />
<icon height="87" src="resources/ios/icon/icon-29@3x.png" width="87" />
<icon height="40" src="resources/ios/icon/icon-40.png" width="40" />
<icon height="80" src="resources/ios/icon/icon-40@2x.png" width="80" />
<icon height="120" src="resources/ios/icon/icon-40@3x.png" width="120" />
<icon height="88" src="resources/ios/icon/icon-44@2x.png" width="88" />
<icon height="50" src="resources/ios/icon/icon-50.png" width="50" />
<icon height="100" src="resources/ios/icon/icon-50@2x.png" width="100" />
<icon height="60" src="resources/ios/icon/icon-60.png" width="60" />
<icon height="120" src="resources/ios/icon/icon-60@2x.png" width="120" />
<icon height="180" src="resources/ios/icon/icon-60@3x.png" width="180" />
<icon height="72" src="resources/ios/icon/icon-72.png" width="72" />
<icon height="144" src="resources/ios/icon/icon-72@2x.png" width="144" />
<icon height="76" src="resources/ios/icon/icon-76.png" width="76" />
<icon height="152" src="resources/ios/icon/icon-76@2x.png" width="152" />
<icon height="167" src="resources/ios/icon/icon-83.5@2x.png" width="167" />
<icon height="172" src="resources/ios/icon/icon-86@2x.png" width="172" />
<icon height="196" src="resources/ios/icon/icon-98@2x.png" width="196" />
<icon height="1024" src="resources/ios/icon/icon-1024.png" width="1024" />
<splash height="480" src="resources/ios/splash/Default~iphone.png" width="320" />
<splash height="960" src="resources/ios/splash/Default@2x~iphone.png" width="640" />
<splash height="1024" src="resources/ios/splash/Default-Portrait~ipad.png" width="768" />
<splash height="768" src="resources/ios/splash/Default-Landscape~ipad.png" width="1024" />
<splash height="1125" src="resources/ios/splash/Default-Landscape-2436h.png" width="2436" />
<splash height="1242" src="resources/ios/splash/Default-Landscape-736h.png" width="2208" />
<splash height="2048" src="resources/ios/splash/Default-Portrait@2x~ipad.png" width="1536" />
<splash height="1536" src="resources/ios/splash/Default-Landscape@2x~ipad.png" width="2048" />
<splash height="2732" src="resources/ios/splash/Default-Portrait@~ipadpro.png" width="2048" />
<splash height="2048" src="resources/ios/splash/Default-Landscape@~ipadpro.png" width="2732" />
<splash height="1136" src="resources/ios/splash/Default-568h@2x~iphone.png" width="640" />
<splash height="1334" src="resources/ios/splash/Default-667h.png" width="750" />
<splash height="2208" src="resources/ios/splash/Default-736h.png" width="1242" />
<splash height="2436" src="resources/ios/splash/Default-2436h.png" width="1125" />
<splash height="2732" src="resources/ios/splash/Default@2x~universal~anyany.png" width="2732" />
</platform>

view raw
config.xml
hosted with ❤ by GitHub

With the icons and splash screens migrated, we can turn our attention to adding any plugins that our PhoneGap Build application uses. The PhoneGap Build system would read the config.xml and use it to install the plugin into the build system. We need to perform this step ourselves. Open the config.xml file that you moved from your original PhoneGap Build folder. Your plugins will be individually listed in elements. The Cordova CLI command to add a plugin is

$ cordova plugin add

For adding the Statusbar plugin it would be:

$ cordova plugin add cordova-plugin-statusbar

If you need to install a specific version of plugin, append the version number after the plugin name. For example, if I wanted to instal the version 2.0.0 of the camera plugin I would use:

$ cordova plugin add cordova-plugin-camera@2.0.0

The final bit of heavy lifting is migrating all the other modifications you may have made to the original config.xml. These are things like app permissions or security settings. Go through the file and copy them into the new config.xml. If you need additional help with an element, see the Cordova documentation.

Once you have migrated the contents of the older config.xml file into the new one, delete the old config.xml from within the www directory. The same is true with the resources directory. Your www directory should only contain your HTML, CSS and JS files

Go ahead and try running the emulate command again

$cordova emulate

It might take longer than the first time, but once it finishes you should see your application running in the emulator!

Next steps…

Now that you have migrated from PhoneGap Build to use the Cordova CLI, there are some additional steps that will still be needed. PhoneGap Build took care of properly signing your applications for development or release. These are steps that you are now going to have to manage and perform. You can read the documentation about signing your applications on the Cordova website.

Good luck in migrating your apps to whatever build solution you use!

Farewell to PhoneGap Build

A few days ago, Adobe finally officially announced the end of PhoneGap Build. You can read the announcement on the Adobe I/O blog

I want to first thank the entire PhoneGap team for everything they have done over the years! PhoneGap Build has been a big part of my professional life for a long time. I gave several workshops on it at Adobe MAX, used it as the foundation for my Intro to Mobile Development course at UCSD, and recorded training for LinkedIn Learning. This simple web service could take my HTML, CSS, and JS and create an app I could run on a phone, bypassing so many headaches of getting a local build to work as almost magical. If you want to see how hard it used to be, try finding some of the original instructions for setting up PhoneGap to work in Xcode. 

I knew the end of PhoneGap Build was coming for some time, but could not formally say anything. The PhoneGap team had either left Adobe or was on to new projects. It was only a matter of time before something would break the ‘Build’. I tried to be as clear as I could on the Adobe forums to people, “It was time to move on.”

Now PhoneGap is not truly dead. When Adobe bought Nitobi all those years ago, what they really bought were two things; the PhoneGap name and the Build service. The code that is PhoneGap was given to the Apache Foundation and is alive and well as Cordova. So one option is to transition from building with the PhoneGap Service and begin building locally. I will have a guide for this ready in a few days. Another option is to migrate to one of the maintained services that do the same task. I have long been a user of the Ionic Framework, and they have a service, Appflow, which can fit the bill nicely. I wrote a migration guide for that service which you can read here []. 

I will be still hanging out in the PhoneGap forums at Adobe for a while, trying to answer questions where I can. Otherwise, look for me hanging out on the Ionic Forums.

Thanks, PhoneGap, and let’s keep pushing the web forward!

phonegap

 

What is the Ionic Framework?

I had the good pleasure of presenting to a full room at the recent SoCal Code Camp on the Ionic Framework. Here are my slides from the talk.

ionic-slide

The Ionic Framework combines Google’s Angular with Apache’s Cordova to create fast and beautiful cross-platform mobile apps for iOS and Android (and Electron or Progressive Web Apps). Built atop the web technologies you know and love, this solution can help take your web skills beyond the browser.

Learn PhoneGap Build

473880-636021952776340473_338x600_thumb

PhoneGap and its open-source sister Apache Cordova simplify cross-platform app development. You can code an app once, and then compile it to run anywhere: iOS, Android, or Windows Phone. PhoneGap Build is the cloud-based version, which allows you to take apps built with HTML, CSS, and JavaScript and compile them into native, store-ready mobile apps. All without any SDKs.

In this course, Chris Griffith introduces the PhoneGap ecosystem and the basics of PhoneGap Build. He shows how to set up an account for development and create, configure, and compile your first project with PhoneGap Build. Once you’ve mastered these fundamentals, Chris shows how to extend your app plugins, debug your app, and then prep it for release in the App Store, Google Play store, or Windows Store.

Duration: 1 hr, 24 minutes

Check it out!

Learn Apache Cordova

lynda-cordova

Apache Cordova is the open-source version of PhoneGap, the leading tool for cross-platform app development. It’s a write-once, run-anywhere solution specifically designed for mobile. But to ensure a smooth cross-platform workflow, it helps to know some setup and configuration basics. In this course, Chris Griffith introduces Apache Cordova and the PhoneGap ecosystem, including the two command-line interface (CLI) tools and the PhoneGap desktop app. He shows how to set up your local system and how to create, configure, and build your first project with the Cordova CLI. Once you’ve mastered the fundamentals, Chris shows how to extend your app with native and third-party plugins that enable features such as QR code detection and geolocation, and debug your app, preview it in an emulator or on an actual device, and then prep it for release in the Apple Store or on Google Play.

Duration: 1 hr, 24 minutes

Check it out!

Building Mobile Apps with the PhoneGap Command-Line Interface

Building Mobile Apps with the PhoneGap Command-Line Interface

My latest title on lynda.com has been released! It is Building Mobile Apps with the PhoneGap Command-Line Interface. Here is the description of the course:

PhoneGap’s command-line interface is a great way to build mobile apps, whether you want to use it to initialize new projects or take apps all the way through testing. In this course Chris Griffith offers a thorough overview of building, emulating, and deploying Android and iOS apps with this powerful tool. He’ll show you how to configure your development environment, and create brand-new projects with the PhoneGap CLI as well as the Apache Cordova CLI (the framework PhoneGap is built on). Then he’ll demonstrate how to test your app, customize and extend the platform to suit your workflow, and compile your app with PhoneGap Developer or PhoneGap Build. Start watching and learn how to kick-start your apps from the command line now with the PhoneGap CLI.

It was a lot of fun recording this title. Hope you enjoy it!

PhoneGap Development Mistakes and How to Avoid Them

Recently I have downloaded a few applications that were built using PhoneGap/Cordova and I was shocked at their poor quality. What was shocking about them, was these errors were actually fairly simple to solve if the developers took just a little bit of time. I am not going to name the apps publicly, but let me outline the issues and their solutions.

Custom Splash Screens

Default PhoneGap Splash Screen

One of the first thing a user sees when they launch an application is the splash screen. By default if you use the PhoneGap Command Line Interface (CLI), it will auto generate a collection of default splash screens and icons, like this one.

It is a fairly straight forward process to replace this assets with your splash screen. You do need to make multiple variations to support the wide range of device screens and orientations.

The simplest method is to just overwrite the sample files with your assets. But you can just as easily go into the proper config.xml file and the changes there.

In fact, that was one of the driving reasons I created ConfiGAP for PhoneGap Build in order to assist that process.

I was also surprised that the application made it through the Apple App Store approval process. Yes it met the requirement to have a splash screen, but you would think the gatekeepers would have flagged it.

Holly Schinsky has a nice blog post outlining all the variations of Icons and Splash Screens as well.

Network Access

In another application, I decided to run a simple test. Would the app still function if my device is in Airplane Mode? The reason behind this test was that this app was a companion application to a major technology conference. If you have been to any tech conference you know that connectivity is always an issue. A great way to check your application for this type of use case is to enable Airplane Mode and see how it handles it. So, what happened in this case?

Well, the app launched, and then sat there trying to connect to some remote server, forever. After several minutes, I closed the app. If you make use of ANY network based data or services, you have to check that you have access to the network.

PhoneGap has the Connection API (also known as the Network Information API) which makes this very simple to do. First, this API can identify the type of network you are using. You can leverage this information to estimate the rough data speed you might get and handle the user experience accordingly. This API will call??? send Online/Offline events, so you can respond to the device losing its network access.

In the case of this app, it should have done a simple API call to see if the network was available for locking up the app in a failed attempt to access the schedule serve

Remote Assets

One of the challenges of mobile app development is the approval process for submission into some app stores. This can be at odds with with development time, especially of you are working toward a fixed date (like a conference). One solution is to display the content as an externally hosted web page and use the In App Browser plug-in. If you are not familiar with this Plug-In, it enables another webview to be opened so you can show additional HTML content.

The developers of this conference app chose to use this solution to display their conference maps. Of course this is the issue that I spoke of before regarding “what if there is no network?”, but the issue here is that In App Browser is not the nicest container for the content. The maps were shown, but with an URL address bar (filled with some long content management system type URL) and some unclear user interface controls. The screen no longer looked like the app that I was just using. Probably not the best user experience for a feature that will be fairly well used.

Instead, the developers should have leveraged the File API, allowing one to download and create local files on the mobile device. After properly checking for network status, they could have downloaded the latest maps onto the device, and referenced them locally in their application to create a better user experience.

Disabling the Web Bounce Effect

Another classic mistake when working with PhoneGap is remembering to disable the web bounce effect. If you are not familiar with this, when you scrolling your content in a web view, when the user reaches the top or bottom, the web view will indicate it has reached that point by bouncing or flashing. This is something that screams web app and really makes the app look poorly developed.

To stop this effect, you simply need to add a few elements to your config.xml file:

If you are using it for Android, then use

<preference name="disallowOverscroll" value="true" />
<preference name="webviewbounce" value="false" />

And for IOS, use like

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

Reviewing on Device

One of the last things to look at is the actual text. I was amazed at how small the text appeared was in the app across multiple devices and it was really poor. I was wondering if the developers actually spent time looking and using their application on a mobile device, or did they just stay on their desktops and using emulators/simulators?

One fundamental rule of mobile development is you have to get it on-device. Now this can be slow and cumbersome (creating signing certificates, installing provisioning profiles, developer settings configured correctly), but the new PhoneGap Developer App can reduce that friction greatly. If you are not familiar with the new tool, it is a free app available for iOS, Android and Window Phone, which allows you to have your local PhoneGap application to run within this on-device shell application. It pretty sweet. Save your file, use the PhoneGap CLI, and run your app on-device as it would truly run. There is no excuse for not seeing your app on a device and ensuring it looks good.

Summary

Hopefully, you have added a few things to your checklist when developing your next PhoneGap application. The platform can do some amazing things, but it does require some extra attention to a few items to help make your apps shine. If you have other lessons learned, please feel to drop me a note.

AppaloozaLA!

AppaloozaLA

I had to miss speaking at the one in San Francisco, but I am back in the saddle to speak at the Los Angeles stop! This is going to be a great event filled with some incredible speakers. Personally, I will be presenting on using PhoneGap Build to quickly build native mobile applications.

The event will be on Saturday, November 15, 2014 from 9:00 AM to 5:00 PM (PST) at the Art Institute of CA-Los Angeles.

For more information, visit the EventBrite page. Hope to see you there!