Ionic 2 Native

Using Cordova Plugins in Ionic 2 with Ionic Native



·

There’s been a lot of confusion around how to use Cordova plugins in Ionic 2, and I think a lot of that stems from ngCordova. This was a great little tool that simplified using native plugins in Ionic 1, it can not be used with Ionic 2.

What ngCordova did was wrap the standard Cordova plugins to make them integrate better with Angular, and provide things like promise support, whereas vanilla Cordova plugins usually rely on callbacks.

There’s a new service in Ionic 2 called Ionic Native which is pretty much a direct replacement for ngCordova. It’s the exact same idea, it wraps the vanilla Cordova plugins so that they integrate more nicely with Angular 2 by adding things like promise and observable support.

Misconceptions about Ionic and Cordova

Before we talk about Ionic Native, I wanted to clear up a big misconception that I’ve been seeing a lot recently. A lot of people have been asking questions like:

“How do I use Cordova plugins in Ionic 2?”

which is certainly a fair question, but I think it’s coming from a lack of understanding of Cordova itself. To put it simply, Cordova is a project that provides web access to native plugins. It is not anything specific to Ionic, and can be used with any framework that is built with Cordova or even none at all. The way you implement a Cordova plugin with Ionic 2 is the same way you do it with Ionic 1, Sencha Touch, jQuery Mobile, or even just a vanilla Javascript web page you’re building with Cordova. The process is basically this:

1) Install the plugin you want to use by running the appropriate command:

cordova plugin add MY-PLUGIN-NAME

2) Use the plugin by accessing the global object it adds to your application:

window.plugins.myplugin.someMethod()

The way you access the plugins functionality will depend on the plugin that you are using (so make sure to check the documentation) but in general that is pretty much how it’s done (there may be some issues related to TypeScript however, so make sure to check the end of this blog post for a discuss on that).

Where I think a lot of confusion is coming from is that a lot of people’s first experience with Cordova is going to be through using Ionic. If you’re using Ionic then you’re probably also going to be using ngCordova because it makes things so much nicer, and that’s probably what most tutorials will guide you through doing.

But to use ngCordova in Ionic 1 (which I want to stress is optional) you need to do some dependency injection like this:

.controller('MainCtrl', function($scope, $state, $cordovaCamera) {

	var options = {};

    $cordovaCamera.getPicture(options).then(function(imageData) {
        //Do something
    }, function(error) {
        //Do something
    });
});

In the example above we have to inject $cordovaCamera from ngCordova before we can use it, so I think a lot of people assume that you have to inject plugins into your code in some manner when using Ionic 2. But you can just as easily skip ngCordova and dependency injection and just use the plugin directly like this:

.controller('MainCtrl', function($scope, $state) {

    var options = {};

    navigator.camera.getPicture(function(imageData){
        //Do something
    }, function(error){
        //Do something
    }, options);
});

You can do the same thing in Ionic 2 without having to worry about importing anything or setting anything up (aside from installing the plugin) and just using the plugin directly, and up until now this is all you could do.

However, the Ionic team have just recently released Ionic Native which as I mentioned is basically the equivalent of ngCordova for Ionic 2. If you’re using Ionic Native then you will need to import some stuff, and I do recommend that you use Ionic Native, but just keep in mind that it is not a requirement. There are a lot of plugins not covered by Ionic Native which you may want to use the old school way.

Before We Get Started

Now that we’ve covered that bit of theory, let’s get into how to actually use Ionic Native (it’s pretty easy, so this section is probably going to be shorter than the last one!).

Before you go through this tutorial, you should have at least a basic understanding of Ionic 2 concepts. You must also already have Ionic 2 installed on your machine.

If you’re not familiar with Ionic 2 already, I’d recommend reading my Ionic 2 Beginners Guide first to get up and running and understand the basic concepts. If you want a much more detailed guide for learning Ionic 2, then take a look at Building Mobile Apps with Ionic 2.

Using Ionic Native

Let’s start out by generating a new Ionic 2 application to worth with by running the following command:

ionic start ionic2-native-demo blank --v2

and then making it the current working directory:

cd ionic2-native-demo

You will need to install the plugin you want to use. Let’s use the Geolocation plugin as an example:

ionic plugin add cordova-plugin-geolocation

Then you will need to import the plugin into the component that you want to use it in. Let’s add it to the automatically generated home page in home.ts:

import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { Geolocation } from 'ionic-native';
import { HomePage } from '../pages/home/home';

@Component({
  template: '<ion-nav [root]="rootPage"></ion-nav>'
})
export class MyApp {

  rootPage: any = HomePage;

  constructor(platform: Platform) {

    platform.ready().then(() => {

    });
  }
}

and then all that is left to do is use it. Since we’ve imported Geolocation into this class, we can use it in anywhere within the class. Let’s add a bit of code to the constructor (which is the first bit of code to run when page is created) to grab the users current coordinates:

import { Component } from '@angular/core';
import { Platform } from 'ionic-angular';
import { Geolocation } from 'ionic-native';
import { HomePage } from '../pages/home/home';

@Component({
  template: '<ion-nav [root]="rootPage"></ion-nav>'
})
export class MyApp {

  rootPage: any = HomePage;

  constructor(platform: Platform) {

    platform.ready().then(() => {

      Geolocation.getCurrentPosition().then((resp) => {
       console.log("Latitude: ", resp.coords.latitude);
       console.log("Longitude: ", resp.coords.longitude);
      });

    });
  }
}

If you run this project now using:

ionic serve

You will see your current location output to the console:

Screenshot 2016-03-07 21.04.30

An important thing to keep in mind when using native plugins is that most of them will not work through the browser. Geolocation (as well as some others) is a bit of a special case because there is also a browser based HTML5 Geolocation API, so it will work in the browser, but others like the Camera plugin will not.

Using a Plugin Not Included in Ionic Native

There are many plugins supported in Ionic Native already, but you’ll likely run into a situation where the plugin you want isn’t included (and depending on the plugin you want to use, it may never be).

The way in which you use a non Ionic Native plugin in Ionic 2 is the same as the way you would use it in any Cordova project, which is however the plugin’s documentation says you should use it. However, there are some extra steps you need to take because TypeScript will cause some problems.

TypeScript likes to know about everything in your application up front, so much so that it will refuse to even build your application if you try to use something that it doesn’t know about.

Unforuntately, most Cordova plugins are incorporated into your project when the project is built for a device, not when you are testing through the browser. In most cases you will access the plugins functionality through the plugins namespace on Window:

window.plugins.somePlugin.doSomething();

or through a global object that is made available by the plugin:

someGlobal.doSomething();

…but TypeScript doesn’t know about this, so it complains:

error TS2339: Property 'plugins' does not exist on type 'Window'.

Fortunately, there’s an easy way to get around this – we just need to tell TypeScript what’s up. To get around the issue with Window, you can just declare an any type directly on the window, i.e:

(<any>window).plugins.somePlugin.doSomething();

or in the case of a global object, you can declare it using:

declare var someGlobal;

above the @Component decorator. It is common to do this for the cordova global, i.e. declare var cordova;. Using those two steps should get your around most TypeScript issues you will face. However, keep in mind that the functionality still doesn’t exist in the browser, so even though your application will build successfully (which is important to be able to deploy it to a device in the first place), if you are testing through the browser your application will still break if you are making a call to the plugin.

Of course, if you’d really like to see the plugin you want to use supported in Ionic Native you can even add support for it yourself.

What to watch next...