はじめに
今回は、以前自作したCordovaプラグイン、cordova-plugin-cache-deleteについて、引数に成功・失敗時のコールバック関数を受け取る形式から、コールバック関数を使わないPromiseベースのプラグインに変更する改修を実施していきます。
関連記事
自作Cordovaプラグイン、cordova-plugin-cache-deleteについて書いた過去記事です。
Webviewのキャッシュを削除するCordovaプラグインを作成しました - 中安拓也のブログ
cordova.exec
について
そもそも、cordova-plugin-cache-deleteで、引数に成功時・失敗時のコールバック関数を受け取る形式を採用していたのは、ネイティブプラットフォーム(今回のプラグインではAndroid)と通信するためのcordova.exec
メソッドが成功時・失敗時のコールバック引数を受け取る仕様になっているためです。
下記がcordova.exec
メソッドになります。第一引数が成功時に呼び出されるコールバック関数、第二引数が失敗時のコールバック関数になっています。以下サイトから引用してます。
Plugin Development Guide - Apache Cordova
cordova.exec(function(winParam) {}, function(error) {}, "service", "action", ["firstArgument", "secondArgument", 42, false]);
上記のcordova.exec
の呼び出し方を変えることで、コールバックを廃止した、Promiseベースのプラグインに変更することができます。そうすることで、コールバックの多重ネスト問題(コールバック地獄)が発生しなくなるなどのメリットがあります。
プラグインの改修
cordova-plugin-cache-deleteのディレクトリ構造です。
. ├── LICENSE.txt ├── README.md ├── package.json ├── plugin.xml ├── src │ └── android │ ├── CacheDelete.java │ └── android.iml └── www └── CacheDelete.js
CordovaプラグインのIFを、コールバック関数を使用する形式から、Promiseを返す形式に変更したいので、プラグインのIF(ネイティブプラットフォームの呼び出し方)を定義している下記のJavaScriptファイルを改修していきます。
改修前: www/CacheDelete.js
var exec = require("cordova/exec"); module.exports = { deleteCache: function (success, error) { exec(success, error, "CacheDelete", "deleteCache", []); }, };
上記は、改修前のJavaScriptファイルになります。success
引数とerror
引数でコールバック関数を受け取り、cordova.exec
メソッドに渡しています。
上記のJavaScriptファイル経由でプラグインを呼び出す場合、次のような形式で呼び出す必要があります。成功時・失敗時のハンドリングを引数のコールバック関数で行っており、戻り値はありません。
CacheDelete.deleteCache(successCallback, errorCallback)
なお、上記のJavaScriptファイルで呼び出されるネイティブプラットフォーム側のコードは以下のようになっています。
src/android/CacheDelete.java
package jp.l08084.plugin; import android.util.Log; import org.apache.cordova.CallbackContext; import org.apache.cordova.CordovaPlugin; import org.json.JSONArray; import org.json.JSONException; import java.io.File; public class CacheDelete extends CordovaPlugin { private static final String TAG = "CacheDelete"; private static final String DELETE_CACHE_MESSAGE = "Cordova CacheDelete.deleteCache() called."; private static final String ERROR_MESSAGE = "Failed to delete the cache, error"; @Override public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException { Log.v(TAG, DELETE_CACHE_MESSAGE); if("deleteCache".equals(action)) { deleteCache(callbackContext); return true; } return false; } private void deleteCache(final CallbackContext callbackContext) { File cacheDir = cordova.getActivity().getApplicationContext().getCacheDir(); clearCacheFolder(cacheDir, callbackContext); } private void clearCacheFolder (File dir, final CallbackContext callbackContext) { try { if (dir != null && dir.isDirectory()) { for (File child : dir.listFiles()) { if (child.isDirectory()) { clearCacheFolder(child, callbackContext); } child.delete(); } } callbackContext.success(); } catch (Exception ex) { Log.e(TAG, ERROR_MESSAGE, ex); callbackContext.error(ERROR_MESSAGE); } } }
処理の成功時にcallbackContext.success();
、失敗時にcallbackContext.error(ERROR_MESSAGE);
を呼び出すことで、JavaScriptファイルから渡された成功時・失敗時のコールバック関数を呼び出しています。
それでは、JavaScriptファイルを改修してPromiseベースのプラグインに切り替えていきます。
改修後: www/CacheDelete.js
var exec = require("cordova/exec"); module.exports = { deleteCache: function () { return new Promise(function(resolve, reject) { exec(resolve, reject, "CacheDelete", "deleteCache", []); }); }, };
成功(success
)、失敗(error
)時に渡していたコールバック関数の代わりにPromiseのresolve
とreject
を渡すように改修しています。
動作確認
改修後のプラグインは以下のように呼び出すことができます。
import { Component } from '@angular/core'; import { Platform } from '@ionic/angular'; // アンビエント宣言 declare var CacheDelete: any; @Component({ selector: 'app-tab1', templateUrl: 'tab1.page.html', styleUrls: ['tab1.page.scss'], }) export class Tab1Page { constructor(private platform: Platform) {} public ngOnInit(): void { this.platform.ready().then(() => { if (this.platform.is('android')) { // delete cache CacheDelete.deleteCache() .then(() => console.log('delete cache success!!')) .catch((error) => console.error(error)); } }); } }
参考サイト
Cordova プラグインのコールバック地獄から脱却!Non-Angular アプリケーションでも Ionic Native を利用するという選択 - Qiita
GitHub - chemerisuk/cordova-plugin-firebase-analytics: Cordova plugin for Firebase Analytics