アシアルブログ

アシアルの中の人が技術と想いのたけをつづるブログです

Cordova/PhoneGapプラグインを使おう

ハイブリッドアプリの弱点とも言われるのが速度であったり、複雑なUIやネイティブの機能を使わないと実現できないような操作性です。最近ではWebひいてはHTML5の機能が充実してきているのでJavaScriptを駆使してできるようになってきていますが、それでも時と場合によってはネイティブと組み合わせる方が効率的であったりします。



Monacaではそのためにプラグイン機能が提供されています。これはCordova/PhoneGap互換の仕組みになっていますので、サードパーティー製のCordova/PhoneGapプラグインを利用することも可能です。そこで今回はMonacaにおけるプラグイン開発の流れを紹介します。



必要なもの





サンプルをダウンロードする



後述しますが、プラグインを呼び出す場合、うまく動かない場合のデバッグが通常の開発に比べると困難です。そこで問題なく動くサンプルを使うことで、後はそこから拡張していくのがお勧めです。サンプルのプラグインはこちらからダウンロードできます。まずこちらのファイルをダウンロードしてください(解凍せずにそのままで大丈夫です)。



プラグインのインストール



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の場合)



iOSで実行した場合の画面は以下の通りです。





iOSにて実行



Androidでも同じように表示されます。





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デバッガーが使えないので何か不具合があった時のデバッグが難しいというのがあげられます。特にメソッドが呼ばれないと言った問題の時は解決に時間がかかりますので、サンプルのプラグインをはじめとして、動くものをベースにして開発するのが良いのではないでしょうか。



JavaScriptObjective-C/Javaとの連携はメッセージを送受信する形で行われます。また、その処理は非同期になりますのでコールバックを使った開発となります。なお、iOSAndroid両方の開発を行う場合はプラグインのメソッド(インタフェース)を合わせておく必要があります。



Monacaではサードパーティー製のCordova/PhoneGapプラグインを利用可能ですが、その動作保証は行っておりませんのでご注意ください。また、任意のプラグインの利用はGoldプラン以上になります。



まとめ



HTML5だけでは難しいネイティブを活用した機能や、速度を重視した処理などはプラグインを使うことで解決できる場合があります。Monacaでもサポートされていますので、アップロードの仕方とその開発法をぜひ覚えてください。



Monaca - HTML5ハイブリッドアプリ開発プラットフォーム