ionic用のプラグインを作ってみたくなったんでやってみる。

環境は

Macで

$ ionic –version

4.0.3

$ cordova –version

8.0.0

となっております。

3つのプロジェクトを作ります

  • Cordovaプラグインのプロジェクト
  • Cordovaプラグインをionic-native化するプロジェクト
  • ionic-native経由でcordovaプラグイン使うionicプロジェクト

Cordovaプラグインのプロジェクト

plugmanを使います。

1
Mac ~/src$ npm install -g plugman

プロジェクト作成

1
2
3
4
5
6
7
8
9
#お好みでplug-inのソースを置いとくフォルダ作成。
Mac ~/src$ mkdir cordova_plugins
Mac ~/src$ cd cordova_plugins/
#プラグインプロジェクト作成
Mac ~/src/cordova_plugins$ plugman create --name HelloWorld --plugin_id cordova-plugin-hello-world --plugin_version 0.0.1
#--nameで指定したフォルダにプロジェクトが作成されるので、移動。
Mac ~/src/cordova_plugins$ cd HelloWorld/
#ターゲットプラットフォーム追加(今回はandroidのみ)
Mac ~/src/cordova_plugins/HelloWorld$ plugman platform add --platform_name android

package.json作成

plugman createpackagejson . で色々聞いてくるので全てそのまま。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Mac ~/src/cordova_plugins/HelloWorld$ plugman createpackagejson .
name: (cordova-plugin-hello-world)
version: (0.0.1)
description:
git repository:
author:
license: (ISC)
About to write to /path/to/src/cordova_plugins/HelloWorld/package.json:

{
  "name": "cordova-plugin-hello-world",
  "version": "0.0.1",
  "description": "",
  "cordova": {
    "id": "cordova-plugin-hello-world",
    "platforms": [
      "android"
    ]
  },
  "keywords": [
    "ecosystem:cordova",
    "cordova-android"
  ],
  "author": "",
  "license": "ISC"
}


Is this OK? (yes)
Mac ~/src/cordova_plugins/HelloWorld$

ここまででこんな感じのプロジェクトになってます。

.
├── package.json
├── plugin.xml
├── src
│   └── android
│       └── HelloWorld.java
└── www
    └── HelloWorld.js

3 directories, 4 files

HelloWorld.javaの修正

生成されたHelloWorld.javaのpackageが文法違反なので適当に直します。

1
2
// package cordova-plugin-hello-world;  //こうじゃなくて
package cordova.plugin.helloworld;      //こう

これに合わせてplugin.xmlも変更。

1
<param name="android-package" value="cordova-plugin-hello-world.HelloWorld" />

1
<param name="android-package" value="cordova.plugin.helloworld.HelloWorld" />

こうする。

本番のパッケージ名はちゃんとしたのつけましょう。

ネイティブコードはこのHelloWorld.javaにガシガシ書いて行くわけですが、今回は生成時に作られたcoolMethodのみで進めます。

この時点でコンパイルできないのが辛い。

Cordovaプラグインをionic-native化するプロジェクト

作ったプラグインは素のjavascriptなのでionic(typescript)から使うには何かと不便。

angularのモジュールに仕立ててDI出来るようにします。

native化プロジェクトはionic-nativeのビルド定義を使います。

cloneして自作プラグイン用のコードを追加して作ります。

プロジェクトフォルダをどこにするか悩むところですが、今回はプラグインのお隣に作成。

1
2
3
4
5
6
7
Mac ~$ cd ~/src/cordova_plugins/
Mac ~/src/cordova_plugins$ git clone https://github.com/ionic-team/ionic-native.git
Mac ~/src/cordova_plugins$ cd ionic-native/
# 組み込み(?) native pluginを削除しとく
Mac ~/src/cordova_plugins/ionic-native$ rm -rf src/@ionic-native/plugins/*
# npmパッケージをインストール
Mac ~/src/cordova_plugins/ionic-native$ npm install

以上でビルド環境ができたので自作プラグイン用のコードを書いていきます。

Native plugin雛形の作成

1
Mac ~/src/cordova_plugins/ionic-native$ gulp plugin:create -n HelloWorld

そうすると

./src/@ionic-native/plugins/hello-world/index.ts

が作成されるので、これを変更します。

まずは@Pluginデコレーターを書きかえ。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
@Plugin({
  pluginName: 'HelloWorld',
  // plugin.xml の <plugin id="cordova-plugin-hello-world" から
  plugin: 'cordova-plugin-hello-world', // npm package name, example: cordova-plugin-camera
  // plugin.xml の <clobbers target="cordova.plugins.HelloWorld" /> から
  pluginRef: 'cordova.plugins.HelloWorld', // the variable reference to call the plugin, example: navigator.geolocation
  repo: '', // the github repository URL for the plugin
  install: '', // OPTIONAL install command, in case the plugin requires variables
  installVariables: [], // OPTIONAL the plugin requires variables
  // サポートプラットフォーム
  platforms: ['Android'] // Array of platforms supported, example: ['Android', 'iOS']
})

メソッド追加します。Observableな呼び出しにしてみました。

1
2
3
4
5
6
7
8
9
export class HelloWorld extends IonicNativePlugin {
....
  @Cordova({
    observable: true
  })
  coolMethod(options: HelloWorldOptions): Observable<any> {
    return;
  }
....

tslintでimportがらみで怒られるので、使用していないimportを外すか、 tslint:disable-next-line:no-unused-variable します。

んでビルド。

1
Mac ~/src/cordova_plugins/ionic-native$ npm run build

~/src/cordova_plugins/ionic-native/dist/@ionic-native/hello-world/ に色々できてればOK。

まだプラグインのコンパイルはできないっぽい。

ionic-native経由でcordovaプラグイン使うionicプロジェクト

普通のionicプロジェクトを作成。

今回はplugin-clientで作成。

1
2
3
4
5
6
7
8
9
Mac ~$ cd ~/src/cordova_plugins/
Mac ~/src/cordova_plugins$ ionic start plugin-client sidemenu
....
? Integrate your new app with Cordova to target native iOS and Android? Yes #Yesにする
....
? Install the free Ionic Pro SDK and connect your app? No #Noで
....

Mac ~/src/cordova_plugins$ cd ./plugin-client/

プラグインとionic-nativeの追加

先に作ったプラグインとionic-nativeを追加します。

1
2
3
4
# プラグイン
Mac ~/src/cordova_plugins/plugin-client$ ionic cordova plugin add ../HelloWorld/
#ionic native
Mac ~/src/cordova_plugins/plugin-client$ npm install --save ../ionic-native/dist/\@ionic-native/hello-world

使う

plugin-client/src/app/app.module.tsに登録。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
....
import { HelloWorld } from '@ionic-native/hello-world';    // 追加
....
@NgModule({
....
  providers: [
....
    HelloWorld,    // 追加
....
  ]
})
....

plugin-client/src/pages/home/home.htmlに

1
<button ion-button (click)="callPluginTest()">test</button>

追加。

plugin-client/src/pages/home/home.tsを以下のように変更。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { HelloWorld } from '@ionic-native/hello-world';    //追加

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  constructor(public navCtrl: NavController, private hw: HelloWorld) { //プラグインをDI

  }
  callPluginTest() {    //追加
    this.hw.coolMethod("cool!!").subscribe(   // これが呼び出し!
      (result) => { alert(result); }
    );
  }
}

実行!

1
Mac ~/src/cordova_plugins/plugin-client$ ionic cordova emulate android --livereload

ここではじめてコンパイルが走ります。

うまくいったら動きます。

手順は簡単だけど知らないとできないのがちょっとイヤ。

デバッグとか修正後の再コンパイルとかどうすんすかね?