はじめに
以前作ったCordovaプラグイン、cordova-plugin-cache-deleteのIonic Nativeを作ります。
Ionic Nativeとは
Ionic NativeとはCordova プラグインのTypeScriptラッパーであり、コールバック関数ベースのCordova プラグインを、PromiseまたはObservableベースに変換する機能を提供します。
cordova-plugin-cache-delete自体は、Ionic Nativeを使わなくてもすでにPromiseでラップ済なので、Promise経由で機能を呼び出すことができるプラグインになっています。 しかし、アンビエント宣言の省略など、他のIonic Nativeを持つCordovaプラグインと平仄を合わせるためにcordova-plugin-cache-deleteについても今回の記事でIonic Nativeを作成して、TypeScriptでラップできるようにします。
環境
今回作成したIonic Nativeは、下記バージョンのIonic(Angular, Cordova)で作成したAndroidアプリ上で動作確認しています。
ionic info
コマンドの実行結果
$ ionic info Ionic: Ionic CLI : 6.11.8 (/usr/local/lib/node_modules/@ionic/cli) Ionic Framework : @ionic/angular 5.6.6 @angular-devkit/build-angular : 0.1102.11 @angular-devkit/schematics : 11.2.11 @angular/cli : 11.2.11 @ionic/angular-toolkit : 3.1.1 Cordova: Cordova CLI : 10.0.0 Cordova Platforms : android 9.1.0 Cordova Plugins : cordova-plugin-ionic-keyboard 2.2.0, cordova-plugin-ionic-webview 4.2.1, (and 5 other plugins) Utility: cordova-res : not installed native-run : not installed System: ios-deploy : 1.9.2 ios-sim : 6.1.2 NodeJS : v12.13.1 (/usr/local/bin/node) npm : 6.14.12 OS : macOS Catalina Xcode : Xcode 12.4 Build version 12D4e
Ionic Native作成
それでは、ionic-team / ionic-nativeリポジトリのDEVELOPER.mdの手順に従って、カスタムIonic Nativeを作成していきます
Ionic Nativeのテンプレートを作成
Ionic Nativeを作成するにあたって、ベースになるテンプレートから作成していきます。
まず、Ionic NativeのリポジトリをForkします。
その後、Forkしたリポジトリをクローンして、クローンしたIonic Nativeのルートディレクトリに移動します。
$ git clone https://github.com/l08084/ionic-native.git $ cd ionic-native
テンプレートの作成に使用するため、なければgulp.jsをインストールします。
$ gulp -v bash: gulp: command not found
$ sudo npm install -g gulp
$ gulp -v CLI version: 2.3.0 Local version: Unknown
gulpのインストールが完了したら、クローンしたIonic Nativeのルート上で、npm i
して環境を整えます。
その後、テンプレートを作成するコマンドである、gulp plugin:create -n CacheDelete
を実行します。
CacheDelete
の部分は、今回Ionic Nativeを作成したいCordovaプラグインの名前です。
$ pwd /Users/takuya/fork/ionic-native $ npm i $ gulp plugin:create -n CacheDelete
gulp plugin:create -n PluginName
コマンドを実行すると、Ionic Nativeの./gulpfile.js
のタスクが呼び出されて、ディレクトリ(src/@ionic-native/plugins/plugin-name/
)とindex.ts
が新規作成されます。
新規作成されたindex.ts
の内容は以下の通りになります。
src/@ionic-native/plugins/cache-delete/index.ts
/** * This is a template for new plugin wrappers * * TODO: * - Add/Change information below * - Document usage (importing, executing main functionality) * - Remove any imports that you are not using * - Remove all the comments included in this template, EXCEPT the @Plugin wrapper docs and any other docs you added * - Remove this note * */ import { Injectable } from '@angular/core'; import { Plugin, Cordova, CordovaProperty, CordovaInstance, InstanceProperty, IonicNativePlugin } from '@ionic-native/core'; import { Observable } from 'rxjs'; /** * @name Cache Delete * @description * This plugin does something * * @usage * ```typescript * import { CacheDelete } from '@ionic-native/cache-delete'; * * * constructor(private cacheDelete: CacheDelete) { } * * ... * * * this.cacheDelete.functionName('Hello', 123) * .then((res: any) => console.log(res)) * .catch((error: any) => console.error(error)); * * ``` */ @Plugin({ pluginName: 'CacheDelete', plugin: '', // npm package name, example: cordova-plugin-camera pluginRef: '', // 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'] }) @Injectable() export class CacheDelete extends IonicNativePlugin { /** * This function does something * @param arg1 {string} Some param to configure something * @param arg2 {number} Another param to configure something * @return {Promise<any>} Returns a promise that resolves when something happens */ @Cordova() functionName(arg1: string, arg2: number): Promise<any> { return; // We add return; here to avoid any IDE / Compiler errors } }
これでテンプレートの作成は完了です。
プラグインラッパーの作成
作成されたindex.ts
をソースコードに記載されているコメント通りに修正していくと下記のようになります。
import { Injectable } from '@angular/core'; import { Plugin, Cordova, IonicNativePlugin } from '@ionic-native/core'; /** * @name Cache Delete * @description * Cordova plugin to delete Webview cache * * @usage * ```typescript * import { CacheDelete } from '@ionic-native/cache-delete'; * * * constructor(private cacheDelete: CacheDelete) { } * * ... * * * this.cacheDelete.deleteCache() * .then((res: any) => console.log(res)) * .catch((error: any) => console.error(error)); * * ``` */ @Plugin({ pluginName: 'CacheDelete', plugin: 'cordova-plugin-cache-delete', pluginRef: 'CacheDelete', repo: 'https://github.com/l08084/cordova-plugin-cache-delete', platforms: ['Android'] }) @Injectable() export class CacheDelete extends IonicNativePlugin { /** * delete a cordova webview cache. * * @returns {Promise<any>} Returns a Promise */ @Cordova({ sync: true }) deleteCache(): Promise<any> { return; } }
Cordovaデコレーターにsync: true
をセットしているのは(@Cordova({ sync: true })
)、Promiseでラップせずに値をそのまま返す必要があるためです。(cordova-plugin-cache-deleteの方ですでに値をPromiseでラップ済のため、Ionic Nativeの方でPromseでラップする必要がない)
Cordovaデコレーターの引数の詳細な内容については、ionic-team / ionic-nativeリポジトリのDEVELOPER.mdに詳しく載っています。
これでIonic Nativeの作成は完了です。
動作確認
作成したIonic Native経由でCordovaプラグインcordova-plugin-cache-deleteを呼び出すことができるかIonicアプリで確認します。
まず、npm run lint
コマンドでコーディング規約に反したコードがないか確認します。
$ npm run lint
Lintエラーが出力されないのを確認したら、npm run build
コマンドでビルドを実施します。
$ npm run build
ビルドが成功すると、このようにdist
ディレクトリが作成されます。
作成されたdist
ディレクトリの構造は以下のようになっています。
dist/@ionic-native/plugins/cache-delete ├── index.d.ts ├── index.js └── ngx ├── bundle.js ├── index.d.ts ├── index.js └── index.metadata.json
続いて、作成したdist
ディレクトリ配下のcache-delete
ディレクトリを、テストしたいIonicアプリのnode_modules/@ionic-native
のディレクトリ配下に移動します。
Ionicアプリから今回作成したIonic Nativeを呼び出します。
Ionic Nativeを呼び出すために、コードを下記のように修正します。
src/app/app.module.ts
import { CacheDelete } from '@ionic-native/cache-delete/ngx'; // ...省略 @NgModule({ // ...省略 providers: [ // ...省略 CacheDelete, // ...省略 ], // ...省略 }) export class AppModule {}
src/app/tab1/tab1.page.ts
import { Component } from '@angular/core'; import { Platform } from '@ionic/angular'; import { CacheDelete } from '@ionic-native/cache-delete/ngx'; @Component({ selector: 'app-tab1', templateUrl: 'tab1.page.html', styleUrls: ['tab1.page.scss'], }) export class Tab1Page { constructor(private platform: Platform, private cacheDelete: CacheDelete) {} public ngOnInit(): void { this.platform.ready().then(() => { if (this.platform.is('android')) { // delete cache this.cacheDelete .deleteCache() .then(() => console.log('delete cache success!!')) .catch((error) => console.error(error)); } }); } public delete(): void { this.cacheDelete .deleteCache() .then(() => console.log('delete cache success!!')) .catch((error) => console.error(error)); } }
上記のIonicアプリをビルドしてシミュレーターで動かすと、今回作成したIonic Native経由でCordovaプラグインの呼び出せることを確認できます。
参考サイト
【ionic】Ionic native pluginの作成|ブログ|West Wind Corporation
Ionic Native Pluginを自作する - Qiita
ionic-native/DEVELOPER.md at master · ionic-team/ionic-native · GitHub
Create Ionic TypeScript wrapper from my Cordova Custom plugins - Stack Overflow
Ionic 4 Cordova Custom Plugin using Ionic-Native - Ionic Native - Ionic Forum