So the first time I wrote a hybrid app in Cordova was around five years ago when I was working writing a prototype for a start up Social Network. The prototype failed due to the instability of our Vanilla JavaScript front-end. This really goes to show how important it is to have a solid front end framework.
Luckily, I was blessed with the information that you could convert your Angular app into a fully functional and native capable hybrid app. And so in this article, we’ll be going over on how to convert your angular app into a cordova hybrid app.
Like I mentioned, after finishing a failed prototype with Vanilla JS, it was then that I learned about how you could use a JavaScript framework instead such as Angular to write your own hybrid app… to many web developers, this is a very comforting, comforting thought.
Now, I can write a whole app with native functionality using the Cordova Framework & Angular and it will run on three platforms (iOS, Android, and Browsers). In order to make this happen, you will have to learn how to use Cordova, a simple, lightweight, f***ing out of control, monster of a framework which has access to every single native function on your device, whether it’s an iOS or Android.
Coming from writing hybrid apps in Vanilla JavaScript, I was very happy to know how much easier things would get once I learned how to render my Angular app correctly using Cordova. And so after many attempts and I mean many attempts; I was successful. Walla! SpotBie! A fully functional app published on the web, iOS, and Android:
iOS
https://apps.apple.com/us/app/spotbie/id1439327004?platform=iphone
Android
https://play.google.com/store/apps/details?id=com.exentriks.spotmee.spotmee&hl=en_US&gl=US
This tutorial uses the following framework versions:
Android:
The biggest problem on this task (rendering the angular app correctly through Cordova on iOS and Android) was finding one big solid document detailing every single step of the process.
And so… here we go!
A you ready to unleash the full power of Cordova? When you use a Framework such as Angular, you become accustomed to quality. Being able to transfer this quality into a mobile app and being able to keep the same code-base for all three apps is incredibly useful.
You will only need to worry about learning two or three frameworks (if you include the back-end) if you choose this path. You will become an expert, and exploit every greatness and weakness that this workflow has to offer.
Don’t get me wrong, like with everything else, there are pros and cons to using this workflow. For me, it has been incredibly robust, loyal (seriously, I even have access to Apple Pay), and easy to work with. There are really a couple of setbacks I can think of when using this set up, I will go over them later throughout this blog.
On a brighter note, keep reading to find out more about how I achieved to release SpotBie using Cordova & Angular!
Writing a Hybrid App with Cordova & Angular; What you should know!
Creating your first hybrid app using cordova starts here. You will need to understand how Cordova works before jumping into this tutorial.
Additionally, if you haven’t already, give the Angular Framework a try or there will be no way you could build an Angular App. Duh. You can read more about it on their website here.
Onto the good stuff.
Converting your Angular app into a Cordova Hybrid App
This is where things get messy. But hey, as long as you love what you do, you will be fine.
We will cover the following steps which will get your hybrid app up and running:
- Setting up base href in your Angular App correctly.
- Adding build scripts into your package.json to trans-compile the app into JavaScript.
- Adding the onDeviceReady function to your main.ts file to bootstrap your app module.
- Adding missing Cordova dependencies to access native device functionality.
- Bridging the gap between Angular and Cordova.
- Building your Cordova app for production in iOS & Android.
1. Setting up base href in your Angular App correctly.
Android
In order to do this, you will have to open your index.prod.html file and add the following lines of code which will aide Cordova in understanding where your base href ( your base url for the application – such as https://example.com/ ). In this case our base href will need to change because our files are going to be read from a different directory since we are going to be using the file-system cordova builds for us instead of the default Angular base path.
Code to add into your index.prod.html file.
<base href="/">
<script>document.write('<base href="' + document.location + '" />');</script>
<script src="cordova.js"></script>
<script>
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
window.open = cordova.InAppBrowser.open
}
</script>
iOS
I had trouble getting this work on iOS because the procedure was not the same as for Android. The project would build but the main index file would not load and I would get this error instead in the safari technology preview console:
“/index.html” not found.
Here’s what you should add into your index.prod.html file’s head section in order for Cordova to fire up your Angular project:
<script>document.write('<base href="' + document.location + '" />');</script>
<script src="cordova.js"></script>
Notice how the base href is written differently by using the document.write JavaScript function instead.
Setting Up your App.
Additionally, you have to add this into your main.ts file.
The first thing you will need to do is get the Cordova framework installed on your development machine.
You will need to run the following commands in your favorite cli interface:
- On Linux and macOS
sudo npm install -g cordova
Then, after installing Cordova, please go ahead and move into your source code’s directory and create the app using the following command:
cordova create hello com.example.hello HelloWorld
Wallah! Your Cordova project is ready for launch! Once you make sure that you provision the right certificates for your app developer profile, you will be able to launch the app with a few commands or through an IDE like XCode for OS X.
cordova create hello com.example.hello HelloWorld
This tutorial is not really dedicated to how to set up your Cordova app so if you want to learn how to do that please read the Cordova documentation.
2. Adding build scripts into your package.json to trans-compile the app into JavaScript.
In order to build your Angular app into the Cordova app you will need to add the following script under your “scripts: { ” section in your package.json file:
"build:android": "ng build --prod --base-href . --output-path /home/spotbie/Desktop/immigration-visa-attorney/www/"
"build:ios": "ng build --prod --base-href . --output-path ~/Desktop/spotbie/immigration-visa-attorney/www/"
Essentially what these scripts do is allow you to build into cordova’s www directory. After running “npm run build:android” or “npm run build:ios” your project will get rendered into their respective folders.
Now when you launch the project using Cordova you will notice that the first page that should be loaded is your Angular project’s home page.
3. Adding the onDeviceReady function to your main.ts file to bootstrap your app module.
Just like we did before, you also want to add the following code to your Angular main.ts file.
//For Cordova Functionality
let onDeviceReady = () => {
platformBrowserDynamic().bootstrapModule(AppModule);
};
document.addEventListener('deviceready', onDeviceReady, false);
So with all that being said, the procedure is the same for both iOS and Android. This function simply bootstraps your AppModule into the browser platform for rendering.
4. Adding missing Cordova dependencies to access native device functionality.
Next up you will want to add all your cordova plugin dependencies starting with the platforms you are building for.
To add the Android or iOS platforms from within your cli type the following commands:
cordova platform add ios
cordova platform add android
I should mention that if you are trying to develop an iOS app it should be from your OS X computer.
To install the plugins you are missing you will need to cd into that platform’s directory and type the following command:
cordova plugin add <plugin name>
This will give you a list of all the plugins you have installed in your cordova project.
5. Bridging the Gap between Angular and Cordova.
BUT HOW??!?!?!? How is it possible to bridge the gap between front-end JavaScript functions and your devices native functionalities. Well, like the song says, “it’s easy once you know how it’s done.” But let’s get serious, how many of you are actually wondering WTF is going on here?
Well it’s actually quite straight forward:
Your Angular application will call functions using component local delegate functions which will invoke the global JavaScript version of the function which in turn has access to the global cordova object! Double Whammy! Guess what, your cordova app is now accessible through your Angular methods.
The magic does not stop there, you can clearly see how many different paths this can lead you down on, the possibilities are end-less.
FOR EXAMPLE: This is something I did to edit the swift file for one of the Cordova plugins we were working on:
Problem: I needed a Cordova plugin which would prompt the Camera permission app as soon as the camera was needed.
Plugins such as https://github.com/Cordobo/cordova-plugin-ios-camera-permissions were only helping add the needed permissions to info.plist which is where you should add all your string messages to be displayed on your app.
So here what ended up happening. The reason WHY I needed the camera was to add a QR Scanner which needs camera permission to be used. The problem was that the QR scanner had to be invoked using Angular through a JS delegator.
The first challenge in doing this however is that I could not possibly use this plugin: https://github.com/bitpay/cordova-plugin-qrscanner because it was outdated for iOS 8.0 as you can see in these screen shots:
So in order to fix this, I had to edit the openSettings Swift method that came with the plugin.
As you can see the error came from these lines:
So that fixed that problem. I was able to compile the app successfully after doing so and move on to the next problem which is how would I be able to move to asking for the native device camera’s permission when the user opened the QR code scanner component within the SpotBie app.