Cordova/PhoneGapプラグインを使おう
ハイブリッドアプリの弱点とも言われるのが速度であったり、複雑なUIやネイティブの機能を使わないと実現できないような操作性です。最近ではWebひいてはHTML5の機能が充実してきているのでJavaScriptを駆使してできるようになってきていますが、それでも時と場合によっ てはネイティブと組み合わせる方が効率的であったりします。
Monacaではそのためにプラグイン機能が提供されています。これはCordova/PhoneGap互換の仕組みになっていますので、サードパーティー製のCordova/PhoneGapプラグインを利用することも可能です。そこで今回はMonacaにおけるプラグイン開発の流れを紹介します。
必要なもの
- iOS Dev Center用の秘密鍵、証明書、プロビジョニング(iOS向けに開発する場合)
サンプルをダウンロードする
後述しますが、プラグインを呼び出す場合、うまく動かない場合のデバッグが通常の開発に比べると困難です。そこで問題なく動くサンプルを使うことで、後はそこから拡張していくのがお勧めです。サンプルのプラグインはこちらからダウンロードできます。まずこちらのファイルをダウンロードしてください(解凍せずにそのままで大丈夫です)。
プラグインのインストール
Monacaで新規プロジェクトを作成したら、 設定>Cordovaプラグインの管理 を選択します。
開いた画面で、Cordovaプラグインのインポートをクリッ クします。
そうするとアップロードダイアログが開きますので、先ほどダウンロードしたサンプルのプラグインをアップロードします。
アップロードが問題なく完了すると、次のように HelloWorldPlugin が表示されるはずです。この時点でプラグインは既に有効になっています。
HTMLを修正
プラグインのインストールが終わったので、HTML側でそれを呼び出すように修正します。scriptタグの内容を次のように修正します。
<script>
// PhoneGap event handler
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
console.log("PhoneGap is ready");
// 修正ここから
window.HelloWorld.say(
function(result) { alert( "success: " + result ); },
function(error) { alert( "error: " + error ); }
);
// 修正ここまで
}
</script>
window.HelloWorld.say
というメソッドは、2つの関数を引数にとっています。成功した場合1つ目、失敗した場合は2つ目の引数が呼ばれる仕組みです。
ビルドして実行
後はいつものようにアプリをビルドしてみましょう。なおMonacaデバッガーではプラグインに対応していませんので、iOS/Androidアプリとしてビルドする必要があります。
iOSで実行した場合の画面は以下の通りです。
Androidでも同じように表示されます。
実際のコードを見る
先ほどの index.html で実行している window.HelloWorld.say ですが、これは plugins/jp.co.asial.helloworld/www/hello_world.js で定義されています。
var HelloWorld = function() {};
HelloWorld.prototype.say = function(success, fail) {
cordova.exec(success, fail, "HelloWorldPlugin","say", []);
};
var helloWorld = new HelloWorld();
module.exports = helloWorld;
この中で実行されている cordova.exec
がネイティブプラグインの実行部になります。 HelloWorldPluginのsayメソッドを実行しています。
iOS用のコード
iOSでは plugins/jp.co.asial.helloworld/src/ios/HelloWorldPlugin.*
が使われています。HelloWorldPlugin.m のコードは次の通りです。
#import "HelloWorldPlugin.h"
@implementation HelloWorldPlugin
- (void) say:(CDVInvokedUrlCommand*)command
{
// get arguments from Javascript
//id arg = [command.arguments objectAtIndex:0];
BOOL arg = YES;
CDVPluginResult* result;
if (arg)
{
// Success Callback
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@"Hello World!"];
[self writeJavascript:[result toSuccessCallbackString:command.callbackId]];
}
else
{
// Error Callback
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
[self writeJavascript:[result toErrorCallbackString:command.callbackId]];
}
}
@end
HelloWorldPluginのsayメソッドが呼ばれています。
そして、resultにCDVCommandStatus_OKまたはCDVCommandStatus_ERRORを送り、writeJavascriptを呼び出 してJavaScript側に返しています。
Android用のコード
Android向けのコードは plugins/jp.co.asial.helloworld/src/android/mobi/monaca/HelloWorldPlugin.java
が使われています。HelloWorldPlugin.java のコードは次の通りです。
package mobi.monaca;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;
/**
* This class echoes a string called from JavaScript.
*/
public class HelloWorldPlugin extends CordovaPlugin {
@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
callbackContext.success("Hello World!");
return true;
}
}
こちらはsuccessのみですが、 callbackContext.success
を呼び出すことでsuccessを呼び出しています。
設定のXML
実際のコードとは別に plugins/jp.co.asial.helloworld/plugin.xml
を用意しています。内容は次の通りです。
<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
id="jp.co.asial.helloworld"
version="0.0.1">
<name>HelloWorldPlugin</name>
<description>HelloWorldPlugin Description</description>
<author>Asial Corporation</author>
<license>Apache 2.0 License</license>
<engines>
<engine name="cordova" version=">=2.9.0" />
</engines>
<js-module src="www/hello_world.js" name="helloworld">
<clobbers target="HelloWorld" />
</js-module>
<platform name="ios">
<config-file target="config.xml" parent="/*">
<feature name="HelloWorldPlugin">
<param name="ios-package" value="HelloWorldPlugin"/>
</feature>
</config-file>
<header-file src="src/ios/HelloWorldPlugin.h" target-dir="src/ios" />
<source-file src="src/ios/HelloWorldPlugin.m" target-dir="src/ios" />
</platform>
<platform name="android">
<config-file target="res/xml/config.xml" parent="/*">
<feature name="HelloWorldPlugin">
<param name="android-package" value="mobi.monaca.HelloWorldPlugin"/>
</feature>
</config-file>
<source-file src="src/android/mobi/monaca/HelloWorldPlugin.java" target-dir="src/mobi/monaca" />
</platform>
</plugin>
この中のjs-moduleというのはJavaScriptの設定になります。
<js-module src="www/hello_world.js" name="helloworld">
<clobbers target="HelloWorld" />
</js-module>
そしてiOSの設定と、
<platform name="ios">
<config-file target="config.xml" parent="/*">
<feature name="HelloWorldPlugin">
<param name="ios-package" value="HelloWorldPlugin"/>
</feature>
</config-file>
<header-file src="src/ios/HelloWorldPlugin.h" target-dir="src/ios" />
<source-file src="src/ios/HelloWorldPlugin.m" target-dir="src/ios" />
</platform>
Androidの設定に分かれています。
<platform name="android">
<config-file target="res/xml/config.xml" parent="/*">
<feature name="HelloWorldPlugin">
<param name="android-package" value="mobi.monaca.HelloWorldPlugin"/>
</feature>
</config-file>
<source-file src="src/android/mobi/monaca/HelloWorldPlugin.java" target-dir="src/mobi/monaca" />
</platform>
iOSまたはAndroid向けのみにプラグインを提供する場合は、もう片方の指定は不要です。しかしハイブリッドアプリとしてマルチプラットフォームに対応させる場合は両プラットフォーム向けの開発が必要になります。
注意点
注意点としてはMonacaデバッガーが使えないので何か不具合があった時のデバッグが難しいというのがあげられます。特にメソッドが呼ばれないと言った問題の時は解決に時間がかかりますので、サンプルのプラグインをはじめとして、動くものをベースにして開発するのが良いのではないでしょうか。
JavaScriptとObjective-C/Javaとの連携はメッセージを送受信する形で行われます。また、その処理は非同期になりますのでコールバックを使った開発となります。なお、iOS、Android両方の開発を行う場合はプラグインのメソッド(インタフェース)を合わせておく必要があります。
Monacaではサードパーティー製のCordova/PhoneGapプラグインを利用可能ですが、その動作保証は行っておりませんのでご注意ください。また、任意のプラグインの利用はGoldプラン以上になります。
まとめ
HTML5だけでは難しいネイティブを活用した機能や、速度を重視した処理などはプラグインを使うことで解決できる場合があります。Monacaでもサポートされていますので、アップロードの仕方とその開発法をぜひ覚えてください。