最初のプラグインを作成する
最初のPhoneGapネイティブプラグインの作成を開始するには、『XcodeとPhoneGapでiOSアプリケーションを開発する』で説明されている手順に従って、新規PhoneGapプロジェクトを作成する必要があります。私のプロジェクトには「MyFirstPhoneGapNativePlugin」という名前を付けました。
JavaScriptクラス
Hello Xcodeプロジェクトをセットアップしたら、ネイティブプラグイン用のJavaScriptインターフェイスを作成できます。ネイティブコードで提供されるロジックに対応するクラスと関数を作成する必要があります。wwwフォルダーの下に、以下のような単純なJavaScriptクラスが含まれるHelloPlugin.jsという名前のJavaScriptファイルを作成します。
var HelloPlugin = { callNativeFunction: function (success, fail, resultType) { return Cordova.exec( success, fail, "com.tricedesigns.HelloPlugin", "nativeFunction", [resultType]); } };
HelloPluginクラスにはcallNativeFunctionという名前の関数が1つあり、この関数は、成功のコールバック関数、失敗のコールバック関数、resultType文字列パラメーターを取ります。callNativeFunction関数で、Cordova.exec関数をラップし、実際のネイティブコードを呼び出します。このクラス内にはその他のJavaScriptはありませんが、必要に応じてここにJavaScriptコードを追加できます。
Cordova.execが呼び出されるとき、5つのパラメーターが渡されます。
- 成功のコールバック関数への参照(ネイティブコードレイヤーからの成功の応答時に呼び出される関数)
- 失敗のコールバック関数(ネイティブレイヤーからの失敗の応答時に呼び出される関数)
- ネイティブコードクラスへの文字列参照(後ほど詳しく説明します)
- 呼び出される関数の名前への文字列参照
- ネイティブコードに渡されるパラメーターの配列
JavaScriptとネイティブコードレイヤー間でのコード実行は、同時進行ではありません。したがって、PhoneGapネイティブプラグインを開発するときには、コールバック関数と非同期のコーディング手法を用いる必要があります。
ネイティブクラス
ネイティブコードレイヤーを作成するには、核となるCordova APIのCDVPluginクラスを拡張する新しいObjective-Cクラスを作成することから始めます。
-
PhoneGapプロジェクト内でPluginsディレクトリを右クリックし、「New File(新規ファイル)」を選択します(図1を参照)。
-
New File(新規ファイル)ウィザードで、Objective-Cクラスのテンプレートを選択し、「Next(次へ)」を選択します(図2を参照)。
-
新規クラス名として「HelloPlugin」と入力し、クラスをCDVPluginのサブクラスにします(図3を参照)。
- 「Next(次へ)」をクリックします。
-
新規ファイルの場所を指定するよう要求されたら指定し(Xcodeプロジェクト内のPluginsディレクトリが望ましい)、「Finish(完了)」をクリックして続行します。PhoneGapプロジェクト内に新しいヘッダーファイル(.h)と実装ファイル(.m)が追加されています(図4を参照)。
-
次に、.hファイルでnativeFunction関数の識別子を追加します。次に例を示します。
#import <Cordova/CDV.h> @interface HelloPlugin : CDVPlugin - (void) nativeFunction:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options; @end
-
クラスのシグネチャーを作成したら、.mファイルのnativeFunction関数のインスタンスにロジックを追加します。このネイティブプラグインのクラス内で使用されるObjective-C関数のサンプルを以下に示します。
#import "HelloPlugin.h" @implementation HelloPlugin - (void) nativeFunction:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options { //get the callback id NSString *callbackId = [arguments pop]; NSLog(@"Hello, this is a native function called from PhoneGap/Cordova!"); NSString *resultType = [arguments objectAtIndex:0]; CDVPluginResult *result; if ( [resultType isEqualToString:@"success"] ) { result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: @"Success :)"]; [self writeJavascript:[result toSuccessCallbackString:callbackId]]; } else { result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString: @"Error :("]; [self writeJavascript:[result toErrorCallbackString:callbackId]]; } } @end
次に、このメソッドは、NSLogを使用してXcodeデバッグコンソールへメッセージを記述します。ここで示されるのは、ネイティブコードを実行していることだけです。
デバッグコンソールへの記述が終わると、関数に渡されたresultTypeを確認し、適切なCDVPluginResultインスタンスが作成されます。resultTypeの値は単純な文字列です。resultTypeが「success」の場合、「成功」の結果が作成され、[self writeJavascript]関数を使用して、JavaScriptレイヤーに対して成功のコールバックが記述されます。resultTypeパラメーターがそれ以外の値の場合、「失敗」の結果が生成され、JavaScriptレイヤーに対して失敗のコールバックが記述されます。
JavaScriptで成功または失敗のコールバック関数を記述するときは、常にCDVPluginResultインスタンスを使用します。ただし、writeJavascript関数を使用してJavaScript文字列をJavaScriptレイヤーに返すこともできます。このテクニックは、ネイティブレイヤーからJavaScriptレイヤーにデータをリアルタイムにプッシュする場合にも利用できます。
プラグインを呼び出す
プラグインが完成したら、PhoneGapアプリケーションから呼び出すことができます。
-
まず、新しいプラグインのJavaScriptインターフェイスクラス(HelloPlugin.js)への参照を追加する必要があります。index.htmlファイルに新しい<script>タグを追加します。
<script type="text/javascript" charset="utf-8" src="HelloPlugin.js"></script>
-
また、onDeviceReady()関数の後に、ネイティブプラグインを呼び出してプラグインの結果を処理するためのJavaScriptを追加します。以下のように、callNativePlugin、nativePluginResultHandler、nativePluginErrorHandlerという名前のJavaScript関数を追加します。
function callNativePlugin( returnSuccess ) { HelloPlugin.callNativeFunction( nativePluginResultHandler, nativePluginErrorHandler, returnSuccess ); } function nativePluginResultHandler (result) { alert("SUCCESS: \r\n"+result ); } function nativePluginErrorHandler (error) { alert("ERROR: \r\n"+error ); }
- callNativePluginは、単にネイティブプラグインクラスのJavaScriptインターフェイスを呼び出すための関数です。この関数がcallNativeFunctionメソッドを呼び出すときに、ネイティブコードレイヤーから受け取る成功および失敗ステータスのコールバック関数が渡されます。ネイティブコードレイヤーから成功のコールバックが返された場合は、nativePluginResultHandler関数が呼び出され、ネイティブコードレイヤーから失敗のコールバックが返された場合は、nativePluginErrorHandler関数が呼び出されます。
-
次に、下記のコードに示すように、プラグインを呼び出すJavaScriptボタンを2つ追加します。
<body onload="onBodyLoad()"> <h1>Hey, it's Cordova!</h1> <button onclick="callNativePlugin('success');">Click to invoke the Native Plugin with an SUCCESS!</button> <button onclick="callNativePlugin('error');">Click to invoke the Native Plugin with an ERROR!</button> </body>
2番目のボタンをクリックすると、callNativeFunctionメソッドが「error」のパラーメーターと共に呼び出されます。PhoneGapは次に、ネイティブコードを実行し、JavaScriptレイヤーで失敗のコールバックを呼び出します(nativePluginErrorHandler関数を呼び出します)。