はじめに
先に、下記の記事を(iOSネイティブプラグイン構築について)発表しました。
CordovaとCouchbase Liteに関する基本については、そちらをご覧ください。
チュートリアル紹介
Couchbase公式チュートリアルとして下記があります。
本稿では、CordovaアプリケーションでCouchbase Liteを使用する方法を解説します。
このチュートリアルでは、AndroidでCouchbase Lite2.xとインターフェイスするCordovaプラグインを構築する方法について説明しています。このチュートリアルでは、フロントエンドWebアプリレイヤーの構築にIonicを使用しています。
チュートリアルでは、Couchbase Liteデータベースに保存されているホテルに関する情報を表示および検索するサンプルアプリケーションが用いられています。
前提条件
このチュートリアルは、次のコンポーネントとバージョンを前提としています。
- Android Studio 3.0
- Android SDK 19
- Couchbase Lite 2.1.0
上記からも分かるように、このチュートリアルは発表時点のテクノロジースタックを元にしています。
開発を始め際には、前提となるフレームワーク、IonicとCordovaの準備が必要になりますが、チュートリアルが提供するサンプルプロジェクトは、過去のバージョンが用いられています。
本稿では、チュートリアルのサンプルアプリそのものの構築からは離れて、Couchbase Liteプラグイン構築手順に焦点を当てて解説します。また、IonicおよびCordovaのインストール手順についても、割愛します。
Couchbase Liteのセットアップ
Couchbase LiteをAndroid Studioプロジェクトにインポートするには、build.gradleに下記の内容を追加します。
dependencies {
implementation fileTree(dir: 'libs', include: '*.jar')
// SUB-PROJECT DEPENDENCIES START
implementation(project(path: ":CordovaLib"))
compile "com.android.support:support-annotations:27.+"
// SUB-PROJECT DEPENDENCIES END
implementation 'com.couchbase.lite:couchbase-lite-android:2.1.0'
}
上記の内容は、チュートリアルで用いられているバージョンに関する記述です。
適宜、下記の記事もご参考ください。
Androidネイティブプラグイン構築手順
Cordovaプラグインを使うと、JavaScriptからネイティブコードに、アクセスすることができます。プラグインは、通常Webベースのアプリでは利用できないデバイスおよびプラットフォーム機能へのアクセスを提供します。
ここtでは、Couchbase LiteのJava APIを使用してcordova-plugin-hotel-listerというプラグインを作成する例を紹介します。
プラグイン定義ファイル
plugin.xml
次のように、plugin.xmlを作成します。
<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android"
id="cordova-plugin-hotel-lister" version="0.0.1">
<name>cordova-plugin-hotel-lister</name>
<description>An Cordova plugin for the Hotel Lister application to implement data persistence using Couchbase Lite.</description>
<license>Couchbase CE / https://www.couchbase.com/binaries/content/assets/website/legal/ce-license-agreement.pdf</license>
<engines>
<engine name="cordova" version=">=3.0.0"/>
</engines>
<js-module src="www/hotel-lister.js" name="HotelLister">
<clobbers target="window.plugins.HotelLister" />
</js-module>
<platform name="android">
<config-file target="res/xml/config.xml" parent="/*">
<feature name="HotelLister">
<param name="android-package" value="com.hotellister.HotelLister"/>
</feature>
</config-file>
<source-file
src="src/android/HotelLister.java"
target-dir="src/com/hotellister/" />
<source-file
src="src/android/Utils.java"
target-dir="src/com/hotellister/" />
</platform>
</plugin>
-
id="cordova-plugin-hotel-lister"
属性は、Ionicプロジェクトでインポートするプラグインの名前です。 - XMLタグ
<js-module></js-module>
は、JavaScriptのインタフェースを宣言しているファイルの場所を示します。 - XMLタグは、ネイティブコードを保持するためのJavaファイルの場所を宣言します。
package.json
次のように、cpackage.jsonを作成します。
{
"name": "cordova-plugin-hotel-lister",
"version": "0.0.1",
"description": "A Cordova plugin for the Hotel Lister app.",
"cordova": {
"id": "cordova-plugin-hotel-lister",
"platforms": [
"android",
"ios"
]
},
"engines": [
{
"name": "cordova",
"version": ">=3.0.0"
}
],
"author": "Couchbase <mobile@couchbase.com>",
"license": "Couchbase CE / https://www.couchbase.com/binaries/content/assets/website/legal/ce-license-agreement.pdf"
}
API定義ファイル
このファイルはプラグインについて説明しています。
Cordova/Ionic Webアプリがプラグインと対話するためのJS APIを定義します。
このことで、プラグインがwindow要素にバインドされます。そうすることで、単純なJavaScript参照を介してアクセスが許可されます。
ここでは、以下のように、hotel-lister.jsという名称のファイルを作成します。
var exec = require('cordova/exec');
var hotelLister = {
/* code will be added here later */
};
module.exports = hotelLister;
ネイティブソース雛形作成
次のように、HotelLister.java
を作成します。こ
のファイルは、hotel-lister.js
で定義されているAPIに対応するネイティブのJava実装を提供します。
package com.hotellister;
import android.content.Context;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaWebView;
import org.json.JSONArray;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class HotelLister extends CordovaPlugin {
@Override
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
super.initialize(cordova, webView);
}
@Override
public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) {
return false;
}
}
Cordovaプラグインは、JavaScript WebViewアプリで最初に呼び出されたときにインスタンス化されます。このpluginInitialized()
メソッドにはスタートアップコードが含まれています。
このexec
メソッドは、JavaSciptからJava側にリクエストをマーシャリングします。
詳細については、以下のプラグインライフサイクルのドキュメントを参照してください。
プラグインインストール
プラグインが期待どおりに機能する準備ができていることを確認するには、プラグインをHotelListerプロジェクトにインストールする必要があります。これを行うには、次のコマンドを実行します。
cordova plugin add ../cordova-plugin-hotel-lister/
成功すると、出力に次のように表示されます。
Adding cordova-plugin-hotel-lister to package.json
Saved plugin info for "cordova-plugin-hotel-lister" to config.xml
新しいネイティブソースの追加
データベース管理クラスを追加します。
以下のように、DatabaseManager.javaを作成します。
package com.hotellister;
import android.content.Context;
import com.couchbase.lite.CouchbaseLiteException;
import com.couchbase.lite.Database;
import com.couchbase.lite.DatabaseConfiguration;
import com.couchbase.lite.FullTextIndex;
import com.couchbase.lite.FullTextIndexItem;
import com.couchbase.lite.IndexBuilder;
public class DatabaseManager {
private static String DB_NAME = "travel-sample";
private static Database database;
private static DatabaseManager instance = null;
private DatabaseManager(Context context) {
if (!Database.exists("travel-sample", context.getFilesDir())) {
String assetFile = String.format("%s.cblite2.zip", DB_NAME);
Utils.installPrebuiltDatabase(context, assetFile);
}
DatabaseConfiguration configuration = new DatabaseConfiguration(context);
try {
database = new Database(DB_NAME, configuration);
} catch (CouchbaseLiteException e) {
e.printStackTrace();
}
}
public static DatabaseManager getSharedInstance(Context context) {
if (instance == null) {
instance = new DatabaseManager(context);
}
return instance;
}
public static Database getDatabase() {
if (instance == null) {
try {
throw new Exception("Must call getSharedInstance first");
} catch (Exception e) {
e.printStackTrace();
}
}
return database;
}
}
このコードでは、まず「travel-sample」という名前のデータベースがデフォルトのCouchbase Liteディレクトリに存在するかどうかを確認します。存在しない場合は、アプリにバンドルされていたtravel-sample.cblite2データベースファイルをデフォルトのCouchbase Liteディレクトリにコピーされます。
このサンプルでは、事前にホテルのデータが登録されたCouchbase Liteデータベースを使っています。そのため、プロジェクトに、事前に構築されたデータベースファイルが追加されていることが前提となります。
plugin.xmlの<platform/>
要素編集
新しいJavaファイルを追加するときは、プラグインの構成ファイルに参照を追加する必要があります。
以下の要素を、plugin.xmlの<platform name="ios"></platform>
要素に挿入します。
<source-file
src="src/android/DatabaseManager.java"
target-dir="src/com/hotellister/" />
ネイティブソース実装追加
次のインポートステートメントをHotelLister.javaの先頭に追加します。
import com.couchbase.lite.CouchbaseLiteException;
import com.couchbase.lite.DataSource;
import com.couchbase.lite.Database;
import com.couchbase.lite.Expression;
import com.couchbase.lite.Meta;
import com.couchbase.lite.Query;
import com.couchbase.lite.QueryBuilder;
import com.couchbase.lite.Result;
import com.couchbase.lite.ResultSet;
import com.couchbase.lite.SelectResult;
HotelLister.javaに次のインスタンス変数を追加します。
private Database database;
次に、HotelLister.javaのinitialize
メソッドを次のように更新して、database
インスタンスプロパティを設定します。
@Override
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
super.initialize(cordova, webView);
Context context = cordova.getContext();
DatabaseManager.getSharedInstance(context);
this.database = DatabaseManager.getDatabase();
}
さらに、データベースからホテルを一覧表示する機能を追加します。
queryHotels
メソッドの実装をHotelLister.javaに追加します。
private List<Result> queryHotels() {
String DOC_TYPE = "hotel";
Query query = QueryBuilder
.select(
SelectResult.expression(Meta.id),
SelectResult.property("address"),
SelectResult.property("phone"),
SelectResult.property("name")
)
.from(DataSource.database(database))
.where(
Expression.property("type")
.equalTo(Expression.string(DOC_TYPE))
);
try {
ResultSet resultSet = query.execute();
return resultSet.allResults();
} catch (CouchbaseLiteException e) {
e.printStackTrace();
return null;
}
}
これで、HotelLister.javaのexecute
メソッドからこのメソッドを呼び出すことができます。
JavaScriptのexec
関数を使用してプラグインにディスパッチされたものはすべて、プラグインクラスのexecute
メソッドに渡されます。
@Override
public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) {
if ("queryHotels".equals(action)) {
List<Result> resultList = queryHotels();
ArrayList<Map<String,Object>> arrayList = new ArrayList<>();
assert resultList != null;
for (Result result : resultList) {
Map<String,Object> map = result.toMap();
arrayList.add(map);
}
JSONArray jsonArray = new JSONArray(arrayList);
callbackContext.success(jsonArray);
return true;
}
return false;
}
次に、プラグインのJavaScriptインターフェースを更新します。hotel-lister.jsに次のコードを追加します。
queryHotels: function(successCallback, errorCallback) {
exec(successCallback, errorCallback, 'HotelLister', 'queryHotels');
},
これで、IonicプロジェクトでqueryHotels
メソッドを呼び出すことができます。home.tsに以下を追加します。
this.platform.ready().then(() => {
window.plugins.HotelLister.queryHotels((hotels) => {
console.log(hotels);
this.hotels = hotels;
});
});
変更をテストするには、Cordovaプラグインをcordova-plugin-hotel-listerからHotelListerに再インストールする必要があります。start-projectフォルダーのルートから次のコマンドを実行します
Cordovaプラグイン再インストール
変更を反映するには、Cordovaプラグインを再インストールする必要があります。
ビルドして実行します。
最後に
本稿では、Cordovaアプリケーション開発のために、Android用のCouchbase Liteネイティブプラグインを構築する手順について解説しました。
Couchbase Liteについての記事を以下の投稿で整理していますので、ご関心に応じて、参照してみてください。
Couchbase Liteは、Couchbase Serverとの自動双方向同期が可能です。
本稿で扱っていない、Couchbase Serverについては、日本語で読むことができるまとまった情報として、次の拙著を紹介させていただきます。