Ionic v3自作プラグインの基礎
Ionic Advent Calendar 2018 の17日目の記事になります。
Ionic界隈ではv4だのCapacitorだので盛り上がっていますが、最近書く機会があったので備忘録程度にv3にて自作プラグイン(Cordova)を追加する方法を書きたいと思います。
プロジェクトの作成
はじめにプロジェクトを作成します。
$ ionic start myApp tabs $ cd myApp
Cordovaプラグインの作成
次に plugman を使ってCordovaプラグインの雛形を作ります。
入っていない場合はインストールしてください。
$ npm install -g plugman
自作プラグインの作業場所として適当に plugins_src
ディレクトリを作ります。
ディレクトリに入り plugman create
コマンドを使ってプラグインを作成します。
$ mkdir plugins_src $ plugman create --name Hoge --plugin_id cordova-plugin-hoge --plugin_version 0.0.0 --path plugins_src
その後 plugman platform add
コマンドにてプラットフォームを追加します。
今回はAndroid用プラグインを作りますが、iOSの場合は適宜書き換えてください。
$ cd plugins_src/Hoge $ plugman platform add --platform_name android
結果、下記のような構成が出来ます。
plugins_src/Hoge/ ├── plugin.xml ├── src │ └── android │ └── Hoge.java └── www └── Hoge.js
中身はこんな感じです。coolMethod、なんてクールな名前なんだ。
やってることは渡ってきた文字列をそのまま返しているだけですね。
<?xml version='1.0' encoding='utf-8'?> <plugin id="cordova-plugin-hoge" version="0.0.0" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android"> <name>Hoge</name> <js-module name="Hoge" src="www/Hoge.js"> <clobbers target="cordova.plugins.Hoge" /> </js-module> <platform name="android"> <config-file parent="/*" target="res/xml/config.xml"> <feature name="Hoge"> <param name="android-package" value="cordova-plugin-hoge.Hoge" /> </feature> </config-file> <config-file parent="/*" target="AndroidManifest.xml"> </config-file> <source-file src="src/android/Hoge.java" target-dir="src/cordova-plugin-hoge/Hoge" /> </platform> </plugin>
var exec = require('cordova/exec'); exports.coolMethod = function (arg0, success, error) { exec(success, error, 'Hoge', 'coolMethod', [arg0]); };
package cordova-plugin-hoge; import org.apache.cordova.CordovaPlugin; import org.apache.cordova.CallbackContext; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; /** * This class echoes a string called from JavaScript. */ public class Hoge extends CordovaPlugin { @Override public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { if (action.equals("coolMethod")) { String message = args.getString(0); this.coolMethod(message, callbackContext); return true; } return false; } private void coolMethod(String message, CallbackContext callbackContext) { if (message != null && message.length() > 0) { callbackContext.success(message); } else { callbackContext.error("Expected one non-empty string argument."); } } }
今回はこれをちょっと編集してメソッドの実行時に一瞬バイブするよう書き換えたいと思います。
ついでにパッケージ名を変更。
<platform name="android"> <config-file parent="/*" target="res/xml/config.xml"> <feature name="Hoge"> - <param name="android-package" value="cordova-plugin-hoge.Hoge" /> + <param name="android-package" value="com.example.hoge.Hoge" /> </feature> </config-file> <config-file parent="/*" target="AndroidManifest.xml"> + <uses-permission android:name="android.permission.VIBRATE" /> </config-file> <source-file src="src/android/Hoge.java" target-dir="src/cordova-plugin-hoge/Hoge" /> </platform>
-package cordova-plugin-hoge; +package com.example.hoge; import org.apache.cordova.CordovaPlugin; import org.apache.cordova.CallbackContext; @@ -7,6 +7,9 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import android.content.Context; +import android.os.Vibrator; + /** * This class echoes a string called from JavaScript. */ @@ -24,6 +27,7 @@ public class Hoge extends CordovaPlugin { private void coolMethod(String message, CallbackContext callbackContext) { if (message != null && message.length() > 0) { + ((Vibrator) cordova.getActivity().getSystemService(Context.VIBRATOR_SERVICE)).vibrate(100); callbackContext.success(message); } else { callbackContext.error("Expected one non-empty string argument.");
最後にプラグインのインストール時に必要となるpackage.jsonを下記のコマンドで作成します。
$ plugman createpackagejson .
CordovaプラグインのIonic Native化
これでCordovaプラグインは完成しましたがIonicで使うためにIonic Native化(Typescript化)します。
任意の場所に ionic-team/ionic-native を置きます。
今回は例として本家を直接サブモジュール化していますが実際使うならフォークしたものを使用してください。
gulp plugin:create -n [プラグイン名]
で雛形を作成します。
$ cd ../.. $ git submodule add https://github.com/ionic-team/ionic-native plugins_src/ionic-native $ cd plugins_src/ionic-native/ $ npm install $ gulp plugin:create -n Hoge
src/@ionic-native/plugins/hoge/index.ts
が出来上がるので下記の様に編集します。
import文はtslintさんが怒ってくるので。
* */ import { Injectable } from '@angular/core'; -import { Plugin, Cordova, CordovaProperty, CordovaInstance, InstanceProperty, IonicNativePlugin } from '@ionic-native/core'; +import { Cordova, CordovaInstance, CordovaProperty, InstanceProperty, IonicNativePlugin, Plugin } from '@ionic-native/core'; import { Observable } from 'rxjs/Observable'; /** @@ -36,24 +36,23 @@ import { Observable } from 'rxjs/Observable'; */ @Plugin({ pluginName: 'Hoge', - plugin: '', // npm package name, example: cordova-plugin-camera - pluginRef: '', // the variable reference to call the plugin, example: navigator.geolocation + plugin: 'cordova-plugin-hoge', // npm package name, example: cordova-plugin-camera + pluginRef: 'cordova.plugins.Hoge', // 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: [] // Array of platforms supported, example: ['Android', 'iOS'] + platforms: ['Android'] // Array of platforms supported, example: ['Android', 'iOS'] }) @Injectable() export class Hoge extends IonicNativePlugin { /** * This function does something - * @param arg1 {string} Some param to configure something - * @param arg2 {number} Another param to configure something + * @param message {string} Some param to configure something * @return {Promise<any>} Returns a promise that resolves when something happens */ @Cordova() - functionName(arg1: string, arg2: number): Promise<any> { + coolMethod(message: string): Promise<any> { return; // We add return; here to avoid any IDE / Compiler errors }
ビルドします。
成果物は dist/@ionic-native/hoge
に置かれます。
これで準備は整ったのでプロジェクト直下に戻ります。
$ npm run build hoge
$ cd ../..
Ionicで実装
最後に実際に使うIonic側のコードを記述します。
src/app/app.module.ts
に登録した後、 src/pages/home/home.ts
にメソッドを追加してボタンで呼ぶようにします。
import { StatusBar } from '@ionic-native/status-bar'; import { SplashScreen } from '@ionic-native/splash-screen'; +import { Hoge } from '@ionic-native/hoge'; @NgModule({ declarations: [ @@ -34,6 +35,7 @@ import { SplashScreen } from '@ionic-native/splash-screen'; providers: [ StatusBar, SplashScreen, + Hoge, {provide: ErrorHandler, useClass: IonicErrorHandler} ] })
import { Component } from '@angular/core'; import { NavController } from 'ionic-angular'; +import { Hoge } from '@ionic-native/hoge'; @Component({ selector: 'page-home', @@ -7,8 +8,14 @@ import { NavController } from 'ionic-angular'; }) export class HomePage { - constructor(public navCtrl: NavController) { + constructor(public navCtrl: NavController, public hoge: Hoge) { } + coolMethod() { + this.hoge.coolMethod('aaaa').then(message => { + alert(message); + }); + } +
Take a look at the <code>src/pages/</code> directory to add or change tabs, update any existing page or create new pages. </p> + <button ion-button (click)="coolMethod()">coolMethod</button> </ion-content>
プラグインをインスールして実機で確認。
$ ionic cordova plugin add plugins_src/Hoge
$ npm install plugins_src/ionic-native/dist/@ionic-native/hoge
$ ionic cordova run android --device
COOLMETHODボタンを押すたびに端末がブルブルと震えるようになりました。
やったね。
まとめ
初歩の初歩ですが割と簡単にできたと思います。
Capacitorだともっと楽にネイティブの機能を呼び出せるっぽいので期待ですね。