Archives

Native Sencha apps with Ext JS 6 and Cordova / PhoneGap

Last time I played with Cordova, I developed Sencha Touch apps. Been there, done that. Sencha’s new mobile framework, is Ext JS 6. With Ext JS 6 you can create desktop applications or mobile (tablets or phone) apps. And.. you can create universal apps. A universal app, means one Ext JS 6 code base, for any type of device. Whether it’s a phone, a tablet or a desktop app, we let Sencha detect the type of device, browser or OS, and download and serve the right kind of experience for you.
That works great for web applications, the so called PWAs, progressive web apps. But what if you want to create a native app with Ext JS? For example, because you want to sell your app in an app store, or because you want to make use of native device API features. The solution would be Adobe PhoneGap or Apache Cordova.

Just in case you are completely new to this technology; PhoneGap and Cordova are making use of the same technology, but PhoneGap is from Adobe and is a commercial solution, Cordova is Apache and open source. The commercial version has a cloud build tool, which can build your applications to native online, (and therefore you don’t need to install dev tools (like for example XCode) on your own machine. Just like how Cordova works, with PhoneGap it’s also possible to build yourself, from your own machine. This requires you to have the SDKs for Android Dev Tools, Windows Tools or XCode installed on your pc or Mac. The way how Cordova/PhoneGap works, is they will take your web build (the Sencha concatenated / minified JavaScript build, index.html and CSS theme), and copy this in a native project file. (like an XCode project). These SDK project files contain a webview (a native shell. It’s like a browser, it can display webpages/apps, you just can’t enter URLs, it defaults to your web build).

Alright, so in the past I’ve wrote tutorials about Cordova and PhoneGap before, you can find those here and here. However, that has been a while ago, and I’m curious to see if it all works the same way, since technologies change, and so do Android and iOS versions.
In particular I’m curious how it will work with Ext JS 6 universal apps. I do want to have one code base for maintainability, however I do not want to have my desktop application deployed with my mobile app, since it’s only for mobiles. Further more, I don’t want to have my Android interface in an iOS build etc.

So let’s dive into this! We will make use of Cordova, since it’s open source there will be many plugins available.

In case you haven’t already. You will need to install Cordova with the NPM package manager, from your command-line. It requires Node. I’m currently running Node JS version: 5.8.0

$ npm install -g cordova

(Mac OSX users might need to prefix the CLI commands with sudo, for the permissions.)

Afterwards, review if Cordova has been correctly installed:

$ cordova -v

Generate a new Ext JS universal app. (Or use an existing one.)
(sencha generate app MyApp ../mypath), you run this command from the downloaded Sencha SDK folder.

Next open from your Ext JS app, the app.json file. We will add some code here.
Scroll to the “builds” block. Add the following build profile:

The “packager” field, will trigger Sencha Cmd, to make use of your Cordova installation.
Note, you can also enter “phonegap” here, in case you have PhoneGap installed on your machine. Once you have the packager defined, you can use the “cordova” object.
In the “platforms” field, you define the platforms you want to build for (again, it requires the SDK tools for every platform). Unless you are creating an application with one universal look and feel (a theme derived from Neptune or Triton), I would put only one platform here. You can always create multiple build profiles in the app.json. I only wrote “ios” here, because my app is making use of the new Ext JS 6.2 “theme-ios” theme. (Remember, that I don’t want to put more than one theme in my build?). The field “remote” is set to false, unless you want to make use of the PhoneGap cloud builder, than it would be “true”. The “id” is the id (reverse domain notation), you will use in your app store, and “name” that’s the name of your app, as you use in Ext.Application.
The “toolkit” property is important for an Ext JS 6 app. (Remember, that I don’t want to include the desktop version of my app in this build?). All phone applications should make use of the toolkit, since that’s a faster performing toolkit, with more components that were designed for mobile touch user experience.

Next. verify, that you didn’t make typos in the app.json file, by running from your project folder the following command:$ sencha app refresh

Now, we need to modify the index.html file, to make sure the application can load within Cordova. The microloader will need to detect if it’s an Cordova app, to load the correct JavaScript code and theme:

This tells the Sencha microloader, to load the “cordovaios” build, if: “cordova” is in the url (to test on your development machine) or if the app runs in a cordova or webview shell.
Sure, instead of all this if else checking, you could force Ext.manifest = ‘cordovaios’ but the magic here, is that we will reuse this index.html for every type of app, whether it’s an desktop app, iOS PWA or Android PWA. So this microloader is actually great.

Ready? Let’s go and build:

$ sencha app build cordovaios

We tell Sencha Cmd to build the “cordovaios” profile, like we wrote in app.json.

Woopie. It seems like it worked. Let’s take a close look and see where the build is located.
According to my build log, it looks like there’s a cordova folder created in my Ext JS application folder:

The www folder, will be the place, where a copy of your Sencha Ext JS 6 app will be located. Let’s look into this folder, and verify what’s inside of it.

So what’s in the cordovaios folder, is the JavaScript code, for the modern toolkit only. Nice!
So. you won’t bundle the desktop version inside of it. And also, it only includes one theme, the right one. This is all because of the “toolkit” and “theme” settings we made in the app.json file.
How awesome.

Let’s cover some Cordova / XCode stuff, since you are here anyway. If you have done this before, this is probably not so interesting for you…

Oh cool. So you are still here.
Open config.xml and modify the name and description fields to describe your app.

After your first build, you can copy the generated cordova.js and cordova-plugins.js files, and put it in your cordova www folder. Copy it from MyApp/cordova/platforms/ios/www. That way the other cordova/www folder won’t have 404 errors.

You could make another build:$ sencha app build cordovaios

Open your application from the cordova www folder in your browser, and verify that everything works without issues. For example:
http://localhost/MyApp/cordova/www/

We don’t need the auto generated css and js folders. So remove those.
No worries, the next time you make a cordovaios build, those folders won’t come back.

Ok, so basically, we could now open XCode, open the MyApp/cordova/platforms/ios/MyApp.xcodeproj, and build with XCode tools, the applications.

In XCode, press the “play” button. It creates a build, and it should run it in an simulator. I run into a common issue:

“The status bar is mixed into my layout.” We can fix this with the cordova-plugin-statusbar plugin. So install it.

Run on the CLI from he cordova folder:$ cordova plugin add cordova-plugin-statusbar

Add to config.xml the following configuration:

In XCode rightclick your project to view the resources/MyApp.pList configuration. And add the following settings:

For iOS developers, the next steps would be to setup an paid Apple Developer account. It cost about a 100 bucks a year, and you can sell unlimited applications from the Apple App Store.
With the developer account, you can get access to iOS beta releases, and you can test your applications on real devices.

Do I need the deltas folder in my hybrid Sencha PhoneGap/Cordova app?

When you create an Ext JS (modern) or Sencha Touch production build, it will make a build for the web. Which is intended for users to bookmark their applications to the homescreen. The microloader contains this great feature; when there is an application update, the user doesn't need to download the full application again, but just the differences. (the delta's). - Everything else will be cached in the localstorage via the microloader, so the app works offline.

This feature, obviously makes no sense, when you want to package your applications as native with PhoneGap/Cordova. Because new application updates will be served via the AppStore. (which require you to re-package the application with PhoneGap/Cordova)

The delta's folder is the magic of all the application differences. - In a native package, you won't need this. The native package also won't need app.cache btw. (because all images will be part of the package).
You can also open app.js, and make sure the onUpdate method will be removed. Because you don't want to refresh the application, and there won't be any delta updates in the package.
Just make sure, you don't serve any deltas in the native package, and that you haven't done this before. ..as soon as deltas are missing, it could break your app.

Why would I need PhoneGap/Cordova for, if I use Sencha / Ext JS?

Sencha applications are (mobile) web applications. They run in a (modern) browser. However, if you want to sell your application as a native application in an App Store, (or you want to make use of native API features), then you can package your application with Cordova or PhoneGap. (It’s a native wrapper, like a browser, with your web app running inside of it).

In case you are curious take a look into my weblog. I wrote a couple of tutorials about Sencha Touch in combination with Cordova / PhoneGap.

With the release of Ext JS 5; we finally have Touch experience in the framework. So yes, you can start creating tablet applications.
Maybe you are now wondering, can I also package Ext JS 5 apps with Apache Cordova or Adobe Phonegap, so I can sell my app in the App Stores?
Well yes, you can!

Here are the steps I took; for porting my app with Cordova/Phonegap.**note, instead of using the keyword phonegap, Cordova users may use the keyword cordova instead.
**note2: you will need to have the following dependencies installed: (Sencha Cmd, Node JS and Phonegap or Cordova)

There we go:

Let's generate a new Ext JS 5 app
Browse with your terminal to your Ext JS 5 SDK folder.
Run the following command:
sencha generate app MyApp ../phonegapdemo
Here we generate an Ext JS 5 demo app, in the phonegapdemo folder, which stands next to the downloaded extjs5 sdk folder.

Here I'm adding a custom phonegap build for iOS. I used as a build name the keyword ios, a name i choose to recognize iOS builds, but incase you want to make for example Android builds, I could change it for android. In case of an Android I would also need to change the platform keyword.
Note also the id property, which expects an id in reversed domain style; and name which should be the name of the Sencha App namespace.
In case I want to build via the Phonegap cloud web service; I should set the property remote to true. Then, you will also need to create a local.properties file in the phonegapdemo folder; with the login details for build.phonegap.com:

Create a native build
Back to your terminal, navigate to the phonegapdemo folder, and run the following command:

sencha app build ios

Note the keyword ios, that's the build name which was set in app.json!
Mac OSX users, might need to prefix with the word sudo.
In case you are using Phonegap cloud webservice, it will now upload your app.
In case of Phonegap local or Cordova, this command will now generate the following folderstructure like below.
Instead of the command sencha app build, I could also use the command sencha app prepare; it would prepare the folderstructure as well.

The www folder, will be the place, where a copy of your Sencha Ext JS 5 app will be located.
The plugin folder will contain Device API plugins after installing those. (see the steps below, woot!)

Enable the JS Phonegap/Cordova API
Although you could build and run your application on a device by now; it might be handy when you enable the Phonegap/Cordova device API.
For example, in case you need to install plugins, such as the inappbrowser plugin.
Open in an editor phonegapdemo/index.html and add the following line, before the micoloader bootstrap.js script:

<script type="text/javascript" src="cordova.js"></script>

You might wonder, why I won't add this cordova.js file to the js array in app.json.
Not sure if I did it wrong, but I was running into sencha build errors because of that. Mind you, the cordova JavaScript
file will be created while building the app; so it's not available in the project root.

Let's build it (again)!

sencha app build ios

In case you are building with the PhoneGap cloud webservice, you can start scanning the QR code.
Cordova or PhoneGap local users, can start opening the project file from the phonegapdemo/phonegap/platforms/<platform> folder,
and build it via the developer toolkit.

Wait, let's add another step, as a BONUS!
What about installing the inAppBrowser plugin, to make sure PhoneGap/Cordova will open your external hyperlinks in browser window within your app!
(That's it's what you want iOS user! Cause iOS ignores opening new browser windows. grrrumbll!!!!)
These steps are for PhoneGap Local / Cordova users:

Edit config.xml
You can find it here: phonegapdemo/phonegap/config.xml
Now add the following line, (if not already available):

<gap:plugin name="org.apache.cordova.inappbrowser"></gap:plugin>

Install the plugin:
Run from the command-line the following command, from the phonegapdemo/phonegap folder:

phonegap plugin add org.apache.cordova.inappbrowser

Again, Mac OSX users, you will need to have admin rights, so prefix with sudo.
This command will add the plugin into the phonegapdemo/phonegap/plugins/ folder.

How to open URLs
Edit the demo app, and create a button, which will open an external URL in a separate browser.
For example:
phonegapdemo/app/view/main/Main.js

In this three-part Sencha Touch tutorial, you will build the Do I need my Umbrella? app, a simple utility app that loads weather information from a web service — worldweatheronline.com. Based on weather codes, this app can predict if you need your umbrella or not.

In this last part of the tutorial, we’ll talk about builds. You’ll use Sencha Cmd as well as PhoneGap/Cordova.

For the native app, you’ll use a native API for retrieving the location of the device, and you’ll port your app to a native mobile app with PhoneGap/Cordova for iOS, Android, BlackBerry10 or Windows Phone.

Note: If you want to test your app on an iOS, BlackBerry or Windows Phone device, you will need authorization keys and developer accounts. Also, if you use Cordova, you can’t build an iOS app in the Windows operating system, nor can you build a Windows app from within Mac OS X.

Creating a production build

With Sencha Cmd, you can create production and test build packages. The production build package compiles the Sass style sheet to production-ready (minified) CSS. It will also copy over your static images and build your JavaScript (Sencha Touch framework classes plus your own custom classes) into a single minified, concatenated file that’s small enough to easily download or cache the file. The production build will also include a cache manifest file to enable local caching.

The test package won’t contain this file. In the test build, the JavaScript and CSS files in the test package won’t be minified and therefore will be readable.

Let’s first create a production build of the Weather application. We’re not going to create a native build yet. In case you want to host the Weather App on your own server, you need to copy the production build folder over to your web server.

On the command-line enter the following command to generate a production build:

sencha app build production

or

sencha app build testing

Review the folder structure. This is the folder structure you can use on your web server, in case you decide to run the mobile application from an online URL.

Perhaps you noticed that the fonts are not copied into the build folder. We could copy this folder manually, or we could modify the build process. Let’s look into these options.

Sencha Cmd uses Apache Ant for the build processes. You can find all the internally used tasks in the hidden .sencha folder.

If you want to modify the build process yourself, you can open the build.xml file in the root of your application folder and add the following Ant task to the end of the file:

All set? That’s great. The only thing that’s left is building a native app with PhoneGap/Cordova.

Building a hybrid app

There are three products you can use to create a native app from a Sencha Touch code base:
Sencha Mobile Packager, Adobe PhoneGap, and Apache Cordova. All products are supported by the Sencha Device API which allows you to access hardware resources on devices.

Let me explain the differences between these three solutions:

Sencha Mobile Packager

Uses the packager.json to build iOS or Android build packages locally that can be distributed through the Android Marketplace or Apple App Store.

Adobe PhoneGap

Lets you use the PhoneGap Build cloud service to (remotely) package your apps and distribute them through the Android Marketplace, BlackBerry App World, Windows Phone Store or Apple App Store. It’s an easy solution, and you can test applications on your device by scanning a QR code. You can also build applications locally. It’s a commercial product, and the free version is limited to one private app.

Apache Cordova

Apache Cordova is a top-level project within the Apache Software Foundation. Cordova is the free, open-source, community-driven version of Adobe PhoneGap. Cordova lets you package apps locally and distribute them through the Android Marketplace, Blackberry App World, Windows Phone Store or Apple App Store.

Note: We will use PhoneGap Build in this tutorial. If you would rather use Cordova, you can use the same commands as you see in the tutorial, but replace the word phonegap with cordova on the command-line.

Initialize a PhoneGap project

The first step in building a hybrid app is to issue the following command from your project’s directory to enable it:

sencha phonegap init <APP-ID> <APP-NAME>

The App ID follows this pattern: <REVERSED-DOMAIN>.<APP-NAME>.

Your application name should be the same value as the name property that you specified in your app.json file.

Note: If you want to port to an iOS app, you will need to make sure that the App Id is the same one that you registered in your Apple provisioning portal.

MyApp/phonegap

MyApp/phonegap contains the full PhoneGap file structure. If you used Cordova to initialize a project, the folder will be named cordova.

phonegap.local.properties

The phonegap.local.properties file contains the names of the platforms that you want when building locally. By default, it takes the local installed SDKs, for example:

phonegap.platforms=ios android blackberry10 wp8

When you run the phonegap init command, the property file also gives you settings for the Adobe PhoneGap remote packager. When you have a PhoneGap Build account, you can set up these additional settings:

When you leave the phonegap.build.remote property as false, you have to have one of the SDKs (XCode, Android Developer Tools, BlackBerry 10 SDK or Windows 8 Pro with Visual Studio) installed on your machine.

The next step is to enable the Geolocation plugin at startup, to retrieve the location via the device:

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

Disable fullscreen mode, to show the status bar (battery indicator and time):

<preference name="fullscreen" value="false"></preference>

Let’s make sure the application supports connections to external urls. The weather application will connect to http://www.worldweatheronline.com. Therefore, we need to give access to either this URL or all external URLs. We can use the wildcard to allow all external connections:

<access origin="*"></access>

The last thing we’ll modify are the paths to the icons and loading images. By default Sencha Touch generated iOS icons and splash images. They can be found in the MyApp/resources folder.

When building apps for iPhones with retina displays (iPhone 5+), it’s important that you provide the correct splash screens with the required screen sizes. If not, your viewport may be resized incorrectly. For this example, we’ll stick to the PhoneGap splash screens. Feel free to replace them with your own splash screens.

It will build the applications in the MyApp/cordova or MyApp/phonegap folder:

platforms/android/bin - Android .apk file

platforms/ios/build/ - iOS .app file

platforms/blackberry10/build/simulator - BlackBerry 10 .bar file

platforms/wp8/Bin/Debug - Windows Phone .xap file

Testing a native build

If you’re using PhoneGap Build, testing the application on Android devices will be very easy. Simply scan the QR code or download, drag and drop the .apk file on the memory card of your phone.

For iOS, you will need provisioning and code signing, which assures users that the app is from a known source and the app hasn’t been modified since it was last signed. Windows Phone developers and iOS developers will need a (paid) developer account.

When all is set, you can build the application with PhoneGap from the command-line interface:

sencha app build native

When you build for iOS, you might run into a build error because you need to code sign the iOS app. With PhoneGap Build, you’ll need to upload the *.p12 certificate and the *.mobileprovisioning mobile provisioning profile. After you’ve uploaded these two keys, you can unlock the keys and rebuild.

If you’re building the app locally, (PhoneGap remote=false or with Cordova), you can open: platforms/ios/Dinmu.xcodeproj from the phonegap or cordova folder, and maintain the build settings to code sign the application. Your developer identity should be in the Code signing identity list. If not, you probably need to go through the whole native provisioning process again.

Make sure your phone is hooked up to your Mac OS X, and build and run in XCode.

Congratulations, you’ve finished building a Sencha Touch utility app from scratch. If you’ve followed all three tutorials in this series, you’ve generated an application with Sencha Cmd and created all the views, models, stores and controllers for the Do I need my Umbrella? app. You’ve created a custom theme with Sass, and you’ve created a production build to host on a web server or built a hybrid app wtih Adobe PhoneGap/Cordova. With this workflow, you’re ready to build any app you like.

Did you like this series of tutorials? Join one of the (advanced) Ext JS and Sencha Touch Training courses. Take a look at the open courses located around the world or join an online class or check out my book that I wrote for O'Reilly: Hands-on Sencha Touch 2 by Lee Boonstra