IMFData または Cloudant SDK を使用して Cloudant にモバイル・データを保管するアプリケーションのマイグレーション

improve this page | report issue

概説

モバイル・アプリケーションのデータを Cloudant データベースに保管できます。Cloudant は、JSON データ、フルテキスト・データ、および地理情報データなどの幅広い種類のデータ・タイプの処理が可能な、拡張 NoSQL データベースです。Java™ 、Objective-C、および Swift 用の SDK があります。

CloudantToolkit および IMFData のフレームワークは IBM Mobile Foundation v8.0 で非推奨になりました

  • iOS の場合は、CloudantToolkit フレームワークおよび IMFData フレームワークの代わりに CDTDatastore SDK を使用します。
  • Android の場合は、CloudantToolkit フレームワークおよび IMFData フレームワークの代わりに Cloudant Sync Android SDK を使用します。Cloudant Sync を使用すると、データをローカル側で永続化させ、リモート・データ・ストアで複製することができます。

リモート・ストアに直接アクセスしたい場合は、アプリケーションで REST 呼び出しを使用し、「Cloudant API Reference」を参照してください。

Cloudant か JSONStore か

以下のシナリオでは、Cloudant の代わりに JSONStore を使用することを検討することをお勧めします。

  • FIPS 140-2 準拠方式で保管される必要があるデータをモバイル・デバイスに保管している場合。
  • デバイスとエンタープライズ間でデータを同期する必要がある場合。
  • ハイブリッド・アプリケーションを開発している場合。

JSONStore について詳しくは、『JSONStore』を参照してください。

ジャンプ先

MobileFirst と Cloudant のセキュリティーの統合

アダプター・サンプル

サンプルをダウンロードするには、「Sample: mfp-bluelist-on-premises」を参照してください。

Bluelist サンプルに含まれるアダプターを理解するには、Cloudant セキュリティーMobileFirst セキュリティー・フレームワークの両方を理解する必要があります。

Bluelist アダプター・サンプルには以下の 2 つの主要な機能があります。

  • MobileFirst OAuth トークンを Cloudant セッション Cookie と交換する。
  • Bluelist サンプルから、Cloudant への必要な admin 要求を実行する。

サンプルでは、サーバー上で admin 権限を求める API 要求を実行する方法を示します (そのようにすることがセキュアである場合)。自分の admin 資格情報をモバイル・デバイスに配置することは可能ですが、モバイル・デバイスからのアクセスを制限することをお勧めします。

Bluelist のサンプルでは、MobileFirst のセキュリティーと Cloudant のセキュリティーを統合します。アダプターのサンプルでは、MobileFirst ID を Cloudant ID にマップします。モバイル・デバイスは、Cloudant セッション Cookie を受け取って、非 admin API 要求を実行します。このサンプルでは、Couch セキュリティー・モデルを使用します。

REST エンドポイントの登録

以下の図は、Bluelist アダプター・サンプルの /enroll エンドポイントによって実行される統合を示したものです。

サンプル統合図

  1. モバイル・デバイスが、MobileFirst OAuth トークンを MobileFirst Server から取得します。
  2. モバイル・デバイスは、 アダプターで /enroll でエンドポイントを呼び出します。
  3. アダプター・サンプルが MobileFirst Server を使用して MobileFirst OAuth トークンを検証します。
  4. 有効である場合は、Cloudant への admin API 要求を実行します。サンプルは、_users データベースで既存の Cloudant ユーザーをチェックします。
    • そのユーザーが存在する場合は、_users データベースで Cloudant ユーザー資格情報を検索します。
    • 新規ユーザーが渡された場合は、 Cloudant 管理者資格情報を使用し、新規 Cloudant ユーザーを作成し、_users データベースに保管します。
    • ユーザーに固有のデータベース名を作成し、Cloudant 上にその名前を持つリモート・データベースを作成します。
    • Cloudant ユーザーに、新しく作成したデータベースの読み取り/書き込み権限を付与します。
    • Bluelist アプリケーションに必要な索引を作成します。
  5. 新規の Cloudant セッション Cookie を要求します。
  6. アダプター・サンプルが、Cloudant セッション Cookie、リモート・データベース名、および Cloudant URL をモバイル・デバイスに返します。
  7. セッション Cookie の有効期限が切れるまで、モバイル・デバイスが、Cloudant に対して直接要求を行います。

セッション Cookie REST エンドポイント

セッション Cookie の有効期限が切れた場合、モバイル・デバイスは Cloudant セッション cookie と MobileFirst OAuth トークンを /sessioncookie エンドポイントで交換できます。

データベースの作成

ローカル・データ・ストアへのアクセス

ローカル・データ・ストアを使用して、オフラインの場合でも、高速にアクセスできるように、クライアント・デバイス上にデータを保管できます。
ローカル・データベースにアクセスするための Store オブジェクトを作成するには、データ・ストアの名前を指定します。

重要: データベース名は小文字でなければなりません。

iOS

変更前 (IMFData/CloudantToolkit を使用):

Objective-C

//Get reference to data manager
IMFDataManager *manager = [IMFDataManager sharedInstance];
NSString *name = @"automobiledb";
NSError *error = nil;

Swift

//Create local store
CDTStore *store = [manager localStore:name error:&error];
let manager = IMFDataManager.sharedInstance()
let name = "automobiledb"

var store:CDTStore?
do {
    store = try manager.localStore(name)
} catch let error as NSError {
    // Handle error
}
変更後 (Cloudant Sync を使用):

Objective-C

// Get reference to datastore manager
CDTDatastoreManager *datastoreManager = existingDatastoreManager;
NSString *name = @"automobiledb";
NSError *error = nil;

//Create datastore
CDTDatastore *datastore = [datastoreManager datastoreNamed:name error:&error];

Swift

// Get reference to datastore manager
let datastoreManager:CDTDatastoreManager = existingDatastoreManager
let name:String  = "automobiledb"

//Create local store
var datastore:CDTDatastore?
do{
    datastore = try datastoreManager.datastoreNamed(name)
}catch let error as NSError{
    // Handle error
}

Android

変更前 (IMFData/CloudantToolkit を使用):
// Get reference to DataManager
DataManager manager = DataManager.getInstance();

// Create local store
String name = "automobiledb";

Task<Store> storeTask = manager.localStore(name);
storeTask.continueWith(new Continuation<Store, Void>() {
    @Override
    public Void then(Task<Store> task) throws Exception {
        if(task.isFaulted()){
            // Handle error
        }else{
            // Do something with Store
            Store store = task.getResult();
        }
        return null;
    }
});
変更後 (Cloudant Sync を使用): Android:
// Create DatastoreManager
   File path = context.getDir("databasedir", Context.MODE_PRIVATE);
   DatastoreManager manager = new DatastoreManager(path.getAbsolutePath());

   // Create a Datastore
       String name = "automobiledb";
       Datastore datastore = manager.openDatastore(name);

リモート・データ・ストアの作成

リモート・ストアにデータを保存するために、データ・ストア名を指定します。

iOS

変更前 (IMFData/CloudantToolkit を使用): iOS:

Objective-c

// Get reference to data manager
IMFDataManager *manager = [IMFDataManager sharedInstance];
NSString *name = @"automobiledb";

// Create remote store
[manager remoteStore:name completionHandler:^(CDTStore *createdStore, NSError *error) {
    if(error){
        // Handle error
    }else{
        CDTStore *store = createdStore;
        NSLog(@"Successfully created store: %@", store.name);
    }
}];

Swift

let manager = IMFDataManager.sharedInstance()
let name = "automobiledb"

manager.remoteStore(name, completionHandler: { (createdStore:CDTStore!, error:NSError!) -> Void in
    if nil != error {
        //Handle error
    } else {
        let store:CDTStore = createdStore
        print("Successfully created store: \(store.name)")
    }
})
変更後 (Cloudant Sync を使用): iOS:

Objective-c

Swift

Android

変更前 (IMFData/CloudantToolkit を使用): Android:
変更後 (Cloudant Sync を使用): Android:

デバイスのデータの暗号化

モバイル・デバイス上のローカル・データ・ストアの暗号化を有効にするには、アプリケーションを更新して暗号化機能を含むようにし、暗号化されたデータ・ストアを作成する必要があります。

iOS デバイスのデータの暗号化

  1. CocoaPods を使用して暗号化機能を取得します。
    • Podfile を開き、以下の行を追加します。
    変更前 (IMFData/CloudantToolkit を使用):
    pod 'IMFDataLocal/SQLCipher'
    
    変更後 (Cloudant Sync を使用): iOS デバイスのデータの暗号化:

    xml pod 'CDTDatastore/SQLCipher'

    詳しくは、CDTDatastore の暗号化に関する資料を参照してください。

    • 以下のコマンドを実行して、アプリケーションに依存関係を追加します。

      bash pod install

  2. Swift アプリケーション内で暗号化機能を使用するには、アプリケーションの関連ブリッジング・ヘッダーに以下の import を追加します。

    変更前 (IMFData/CloudantToolkit を使用): iOS デバイスのデータの暗号化:
    #import <CloudantSync.h>
    #import <CloudantSyncEncryption.h>
    #import <CloudantToolkit/CloudantToolkit.h>
    #import <IMFData/IMFData.h>
    
    変更後 (Cloudant Sync を使用): iOS デバイスのデータの暗号化 (Swift):
    #import <CloudantSync.h>
    #import <CloudantSyncEncryption.h>
    
  3. 暗号化を行うように鍵プロバイダーと共にローカル・ストアを初期化します。

    警告: データベースを作成した後でパスワードを変更すると、既存のデータベースを暗号化解除できなくなるため、エラーが発生します。データベースが暗号化された後でパスワードを変更することはできません。パスワードを変更するには、データベースを削除する必要があります。

    変更前 (IMFData/CloudantToolkit を使用) : 暗号化のためのローカル・ストアの初期化:

    Objective-C

    //Get reference to data manager
    IMFDataManager *manager = [IMFDataManager sharedInstance];
    NSString *name = @"automobiledb";
    NSError *error = nil;
    
    // Initalize a key provider
    id<CDTEncryptionKeyProvider> keyProvider = [CDTEncryptionKeychainProvider providerWithPassword: @"passw0rd" forIdentifier: @"identifier"];
    
    //Initialize local store
    CDTStore *localStore = [manager localStore: name withEncryptionKeyProvider: keyProvider error: &error];
    

    Swift

    let manager = IMFDataManager.sharedInstance()
    let name = "automobiledb"
    
    let keyProvider = CDTEncryptionKeychainProvider(password: "passw0rd", forIdentifier: "identifier")
    var store:CDTStore?
    do {
         store = try manager.localStore(name, withEncryptionKeyProvider: keyProvider)
    } catch let error as NSError {
         // Handle error
    }
    
    変更後 (Cloudant Sync を使用) : 暗号化のためのローカル・ストアの初期化:

    Objective-C

    // Get reference to datastore manager
    CDTDatastoreManager *datastoreManager = existingDatastoreManager;
    NSString *name = @"automobiledb";
    NSError *error = nil;
    
    // Create KeyProvider
    id<CDTEncryptionKeyProvider> keyProvider = [CDTEncryptionKeychainProvider providerWithPassword: @"passw0rd" forIdentifier: @"identifier"];
    
    //Create local store
    CDTDatastore *datastore = [datastoreManager datastoreNamed:name withEncryptionKeyProvider:keyProvider error:&error];
    

    Swift

    // Get reference to datastore manager
    let datastoreManager:CDTDatastoreManager = existingDatastoreManager
    let name:String  = "automobiledb"
    
    //Create local store
    var datastore:CDTDatastore?
    let keyProvider = CDTEncryptionKeychainProvider(password: "passw0rd", forIdentifier: "identifier")
    do{
         datastore = try datastoreManager.datastoreNamed(name, withEncryptionKeyProvider: keyProvider)
    }catch let error as NSError{
         // Handle error
    }
    
  4. 暗号化されたローカル・ストアを使用してデータを複製する場合、CDTPullReplication メソッドおよび CDTPushReplication メソッドを鍵プロバイダーと共に初期化する必要があります。

    変更前 (IMFData/CloudantToolkit を使用) : 鍵プロバイダーとともに初期化:

    Objective-C

    //Get reference to data manager
    IMFDataManager *manager = [IMFDataManager sharedInstance];
    NSString *databaseName = @"automobiledb";
    
    // Initalize a key provider
    id<CDTEncryptionKeyProvider> keyProvider = [CDTEncryptionKeychainProvider providerWithPassword:@"password" forIdentifier:@"identifier"];
    
    // pull replication
    CDTPullReplication *pull = [manager pullReplicationForStore: databaseName withEncryptionKeyProvider: keyProvider];
    
    // push replication
    CDTPushReplication *push = [manager pushReplicationForStore: databaseName withEncryptionKeyProvider: keyProvider];
    

    Swift

    //Get reference to data manager
    let manager = IMFDataManager.sharedInstance()
    let databaseName = "automobiledb"
    
    // Initalize a key provider
    let keyProvider = CDTEncryptionKeychainProvider(password: "password", forIdentifier: "identifier")
    
    // pull replication
    let pull:CDTPullReplication = manager.pullReplicationForStore(databaseName, withEncryptionKeyProvider: keyProvider)
    
    // push replication
    let push:CDTPushReplication = manager.pushReplicationForStore(databaseName, withEncryptionKeyProvider: keyProvider)
    
    変更後 (with Cloudant Sync) : 鍵プロバイダーとともに初期化:

    暗号化データベースで複製を行う場合に、暗号化されていないデータベースでの複製に変更を加える必要はありません。

Android デバイスのデータの暗号化

Android デバイス上のデータを暗号化するには、アプリケーションに正しいライブラリーを組み込むことによって暗号化機能を取得します。その後、暗号化用のローカル・ストアを初期化し、データを複製できます。

  1. build.gradle ファイル内で Cloudant Toolkit ライブラリーを依存関係として追加します。

    変更前 (IMFData/CloudantToolkit を使用): Android デバイスのデータの暗号化:
    repositories {
    mavenCentral()
    }
    
    dependencies {
        compile 'com.ibm.mobile.services:cloudant-toolkit-local:1.0.0'
    }
    
    変更後 (Cloudant Sync を使用): Android デバイスのデータの暗号化:
     repositories {
         mavenLocal()
         maven { url "http://cloudant.github.io/cloudant-sync-eap/repository/" }
         mavenCentral()
     }
    
     dependencies {
         compile group: 'com.cloudant', name: 'cloudant-sync-datastore-core', version:'0.13.2'
         compile group: 'com.cloudant', name: 'cloudant-sync-datastore-android', version:'0.13.2'
         compile group: 'com.cloudant', name: 'cloudant-sync-datastore-android-encryption', version:'0.13.2'
     }
    
  2. SQLCipher for Android v3.2.jar および .so バイナリー・ファイルをダウンロードし、それらのファイルを、アプリケーション構造内の適切なフォルダー内でアプリケーションに組み込みます。
    • ライブラリーを追加します。共有ライブラリー・ファイルおよび SQLCipher アーカイブを、Android アプリケーション・ディレクトリーの jniLibs フォルダーに追加します。
    • 必要な ICU 圧縮ファイルをアプリケーションの assets フォルダーに追加します。
    • sqlcipher.jar をファイル依存関係として追加します。Android Studio のアプリケーション・フォルダーのメニューから、「モジュール設定を開く」の下の「依存関係」タブを選択します。
  3. 暗号化を行うように鍵プロバイダーと共にローカル・ストアを初期化します。

    警告: データベースを作成した後でパスワードを変更すると、既存のデータベースを暗号化解除できなくなるため、エラーが発生します。データベースが暗号化された後でパスワードを変更することはできません。パスワードを変更するには、データベースを削除する必要があります。

    変更前 (IMFData/CloudantToolkit を使用) : ローカル・ストアの初期化 (Android):
    // Get reference to DataManager
    DataManager manager = DataManager.getInstance();
    
    // Initalize a key provider
    KeyProvider keyProvider = new AndroidKeyProvider(getContext(),"password","identifier");
    
    // Create local store
    String databaseName = "automobiledb";
    Task<Store> storeTask = manager.localStore(databaseName, keyProvider);
    storeTask.continueWith(new Continuation<Store, Void >() {
         @Override
         public Void then(Task<Store> task) throws Exception {
             if (task.isFaulted()) {
                 // Handle error
             } else {
                 // Do something with Store
                 Store store = task.getResult();
             }
             return null;
          }
    });
    
    変更後 (Cloudant Sync を使用) : ローカル・ストアの初期化 (Android):
    // Load SQLCipher libs
    SQLiteDatabase.loadLibs(context);
    
    // Create DatastoreManager
    File path = context.getDir("databasedir", Context.MODE_PRIVATE);
    DatastoreManager manager = new DatastoreManager(path.getAbsolutePath());
    
    // Create encrypted local store
    String name = "automobiledb";
    
    KeyProvider keyProvider = new AndroidKeyProvider(context,"passw0rd","identifier");
    Datastore datastore = manager.openDatastore(name, keyProvider);
    
  4. 暗号化されたローカル・ストアを使用してデータを複製する場合、KeyProvider オブジェクトを pullReplicationForStore() メソッドまたは pushReplicationForStore() メソッドに渡す必要があります。

    変更前 (IMFData/CloudantToolkit を使用): 鍵プロバイダーとともに初期化 (Android):
    //Get reference to data manager
    DataManager manager = DataManager.getInstance();
    String databaseName = "automobiledb";
    
    // Initalize a key provider
    KeyProvider keyProvider = new AndroidKeyProvider(getContext(),"password","identifier");
    
    // pull replication
    Task<PushReplication> pullTask = manager.pullReplicationForStore(databaseName, keyProvider);
    
    // push replication
    Task<PushReplication> pushTask = manager.pushReplicationForStore(databaseName, keyProvider);
    
    変更後 (Cloudant Sync を使用): 鍵プロバイダーとともに初期化 (Android)

    暗号化データベースで複製を行う場合に、暗号化されていないデータベースでの複製に変更を加える必要はありません。

ユーザー・アクセス権の設定

リモート・データベースに対するユーザー・アクセス権を設定できます。

変更前 (IMFData/CloudantToolkit を使用): ユーザー・アクセス権の設定:

Objective-C

// Get reference to data manager
IMFDataManager *manager = [IMFDataManager sharedInstance];

// Set permissions for current user on a store
[manager setCurrentUserPermissions: DB_ACCESS_GROUP_MEMBERS forStoreName: @"automobiledb" completionHander:^(BOOL success, NSError *error) {
    if(error){
        // Handle error
    }else{
        // setting permissions was successful
    }
}];

Swift

// Get reference to data manager
let manager = IMFDataManager.sharedInstance()

// Set permissions for current user on a store
manager.setCurrentUserPermissions(DB_ACCESS_GROUP_MEMBERS, forStoreName: "automobiledb") { (success:Bool, error:NSError!) -> Void in
    if nil != error {
        // Handle error
    } else {
        // setting permissions was successful
    }
}

Java

Task<Boolean> permissionsTask = manager.setCurrentUserPermissions(DataManager.DB_ACCESS_GROUP_MEMBERS, "automobiledb");

permissionsTask.continueWith(new Continuation<Boolean, Object>() {
    @Override
    public Object then(Task<Boolean> task) throws Exception {
        if(task.isFaulted()){
            // Handle error
        }else{
           // setting permissions was successful
        }
        return null;
    }
});
変更後 (Cloudant Sync を使用): ユーザー・アクセス権の設定:

モバイル・デバイスからユーザー・アクセス権を設定することはできません。Cloudant ダッシュボードまたはサーバー・サイド・コードを使用してアクセス権を設定する必要があります。MobileFirst OAuth のトークンと Cloudant のセキュリティーとの統合方法のサンプルについては、Bluelist サンプルを参照してください。

データのモデル化

Cloudant はデータを JSON ドキュメントとして保管します。アプリケーションでオブジェクトとしてデータを保管するには、ネイティブ・オブジェクトを基盤の JSON ドキュメント形式にマップする、付属のデータ・オブジェクト・マッパー・クラスを使用します。

  • iOS: Cloudant はデータを JSON ドキュメントとして保管します。CloudantToolkit フレームワークは、ネイティブ・オブジェクトと JSON ドキュメントの間でマッピングを行うためのオブジェクト・マッパーを備えていました。CDTDatastore API には、この機能はありません。以降のセクションにおけるスニペットでは、CDTDatastore オブジェクトを使用して同じ操作を実現する方法を示します。
  • Android: AndroidCloudant はデータを JSON ドキュメントとして保管します。CloudantToolkit API は、ネイティブ・オブジェクトと JSON ドキュメントの間でマッピングを行うためのオブジェクト・マッパーを備えていました。Cloudant Sync には、この機能はありません。以降のセクションにおけるスニペットでは、DocumentRevision オブジェクトを使用して同じ操作を実現する方法を示します。

CRUD 操作の実行

データ・ストアの内容を変更できます。

  • createretrieveupdate、および delete (CRUD) の操作について詳しくは、CDTDatastore の CRUD の資料を参照してください。
  • リモート・ストアでの createretrieveupdate、および delete (CRUD) の操作については、Cloudant 文書 API を参照してください。

データの作成

変更前

Objective-C

// Use an existing store
CDTStore *store = existingStore;

// Create your Automobile to save
Automobile *automobile = [[Automobile alloc] initWithMake:@"Toyota" model:@"Corolla" year: 2006];

[store save:automobile completionHandler:^(id savedObject, NSError *error) {
    if (error) {
        // save was not successful, handler received an error
    } else {
        // use the result
        Automobile *savedAutomobile = savedObject;
        NSLog(@"saved revision: %@", savedAutomobile);
    }
}];

Swift

// Use an existing store
let store:CDTStore = existingStore

// Create your object to save
let automobile = Automobile(make: "Toyota", model: "Corolla", year: 2006)

store.save(automobile, completionHandler: { (savedObject:AnyObject!, error:NSError!) -> Void in
   if nil != error {
       //Save was not successful, handler received an error
   } else {
       // Use the result
       print("Saved revision: \(savedObject)")
   }
})

Java

// Use an existing store
Store store = existingStore;

// Create your object to save
Automobile automobile = new Automobile("Toyota", "Corolla", 2006);

// Save automobile to store
Task<Object> saveTask = store.save(automobile);
saveTask.continueWith(new Continuation<Object, Void>() {
    @Override
    public Void then(Task<Object> task) throws Exception {
        if (task.isFaulted()) {
            // save was not successful, task.getError() contains the error
        } else {
            // use the result
            Automobile savedAutomobile = (Automobile) task.getResult();
        }
        return null;
    }
});

変更後

// Use an existing store
CDTDatastore *datastore = existingDatastore;

// Create document body
CDTMutableDocumentRevision * revision = [CDTMutableDocumentRevision revision];
revision.body = @{@"@datatype" : @"Automobile", @"make" :@"Toyota", @"model": @"Corolla", @"year" : @2006};

NSError *error = nil;
CDTDocumentRevision *createdRevision = [datastore createDocumentFromRevision:revision error:&error];

if (error) {
        // save was not successful, handler received an error
} else {
    // use the result
    NSLog(@"Revision: %@", createdRevision);
}

Swift

// Use an existing store
let datastore:CDTDatastore = existingDatastore

// Create document body
let revision = CDTMutableDocumentRevision()
revision.setBody(["make":"Toyota","model":"Corolla","year":2006])

var createdRevision:CDTDocumentRevision?
do{
    createdRevision = try datastore.createDocumentFromRevision(revision)
    NSLog("Revision: \(createdRevision)");
}catch let error as NSError{
    // Handle error
}

Java

// Use an existing store
Datastore datastore = existingStore;

// Create document body
Map<String, Object> body = new HashMap<String, Object>();
body.put("@datatype", "Automobile");
body.put("make", "Toyota");
body.put("model", "Corolla");
body.put("year", 2006);

// Create revision and set body
MutableDocumentRevision revision  = new MutableDocumentRevision();
revision.body = DocumentBodyFactory.create(body);

// Save revision to store
DocumentRevision savedRevision = datastore.createDocumentFromRevision(revision);

データの読み取り

変更前

Objective-C

CDTStore *store = existingStore;
NSString *automobileId = existingAutomobileId;

// Fetch Autombile from Store
[store fetchById:automobileId completionHandler:^(id object, NSError *error) {
    if (error) {
        // fetch was not successful, handler received an error
    } else {
        // use the result
        Automobile *savedAutomobile = object;
        NSLog(@"fetched automobile: %@", savedAutomobile);
    }
}];

Swift

// Using an existing store and Automobile
let store:CDTStore = existingStore
let automobileId:String = existingAutomobileId

// Fetch Autombile from Store
store.fetchById(automobileId, completionHandler: { (object:AnyObject!, error:NSError!) -> Void in
    if nil != error {
        // Fetch was not successful, handler received an error
    } else {
        // Use the result
        let savedAutomobile:Automobile = object as! Automobile
        print("Fetched automobile: \(savedAutomobile)")
    }
})

Java

// Use an existing store and documentId
Store store = existingStore;
String automobileId = existingAutomobileId;

// Fetch the automobile from the store
Task<Object> fetchTask = store.fetchById(automobileId);
fetchTask.continueWith(new Continuation<Object, Void>() {
    @Override
    public Void then(Task<Object> task) throws Exception {
        if (task.isFaulted()) {
            // fetch was not successful, task.getError() contains the error
        } else {
            // use the result 
            Automobile fetchedAutomobile = (Automobile) task.getResult();
        }
        return null;
    }
});

変更後

Objective-C

// Use an existing store and documentId
CDTDatastore *datastore = existingDatastore;
NSString *documentId = existingDocumentId;

// Fetch the CDTDocumentRevision from the store
NSError *error = nil;
CDTDocumentRevision *fetchedRevision = [datastore getDocumentWithId:documentId error:&error];

if (error) {
        // fetch was not successful, handler received an error
} else {
    // use the result
    NSLog(@"Revision: %@", fetchedRevision);
}

Swift

// Use an existing store and documentId
let datastore:CDTDatastore = existingDatastore
let documentId:String = existingDocumentId

var fetchedRevision:CDTDocumentRevision?
do{
    fetchedRevision = try datastore.getDocumentWithId(documentId)
    NSLog("Revision: \(fetchedRevision)");
}catch let error as NSError{
    // Handle error
}

Java

// Use an existing store and documentId
Datastore datastore = existingStore;
String documentId = existingDocumentId;

// Fetch the revision from the store
DocumentRevision fetchedRevision = datastore.getDocument(documentId);

データの更新

変更前

Objective-C

// Use an existing store and Automobile
CDTStore *store = existingStore;
Automobile *automobile = existingAutomobile;

// Update some of the values in the Automobile
automobile.year = 2015;

// Save Autombile to the store
[store save:automobile completionHandler:^(id savedObject, NSError *error) {
    if (error) {
        // sasve was not successful, handler received an error
    } else {
        // use the result
        Automobile *savedAutomobile = savedObject;
        NSLog(@"saved automobile: %@", savedAutomobile);
    }
}];

Swift

// Use an existing store and Automobile
let store:CDTStore = existingStore
let automobile:Automobile = existingAutomobile

// Update some of the values in the Automobile
automobile.year = 2015

// Save Autombile to the store
store.save(automobile, completionHandler: { (savedObject:AnyObject!, error:NSError!) -> Void in
    if nil != error {
        // Update was not successful, handler received an error
    } else {
        // Use the result
        let savedAutomobile:Automobile = savedObject as! Automobile
        print("Updated automobile: \(savedAutomobile)")
    }
})

Java

// Use an existing store and Automobile
Store store = existingStore;
Automobile automobile = existingAutomobile;

// Update some of the values in the Automobile
automobile.setYear(2015);

// Save automobile to store
Task<Object> saveTask = store.save(automobile);
saveTask.continueWith(new Continuation<Object, Void>() {
    @Override
    public Void then(Task<Object> task) throws Exception {
        if (task.isFaulted()) {
            // save was not successful, task.getError() contains the error
        } else {
            // use the result
            Automobile savedAutomobile = (Automobile) task.getResult();
        }
        return null;
    }
});

変更後

Objective-C

// Use an existing store and document
CDTDatastore *datastore = existingDatastore;
CDTMutableDocumentRevision *documentRevision = [existingDocumentRevision mutableCopy];

// Update some of the values in the revision
[documentRevision.body setValue:@2015 forKey:@"year"];

NSError *error = nil;
CDTDocumentRevision *updatedRevision = [datastore updateDocumentFromRevision:documentRevision error:&error];
if (error) {
    // save was not successful, handler received an error
} else {
    // use the result
    NSLog(@"Revision: %@", updatedRevision);
}

Swift

// Use an existing store and document
let datastore:CDTDatastore = existingDatastore
let documentRevision:CDTMutableDocumentRevision = existingDocumentRevision.mutableCopy()

// Update some of the values in the revision
documentRevision.body()["year"] = 2015

var updatedRevision:CDTDocumentRevision?
do{
    updatedRevision = try datastore.updateDocumentFromRevision(documentRevision)
    NSLog("Revision: \(updatedRevision)");
}catch let error as NSError{
    // Handle error
}

Java

// Use an existing store and documentId
// Use an existing store
Datastore datastore = existingStore;

// Make a MutableDocumentRevision from the existing revision
MutableDocumentRevision revision = existingRevision.mutableCopy();

// Update some of the values in the revision
Map<String, Object> body = revision.getBody().asMap();
body.put("year", 2015);
revision.body = DocumentBodyFactory.create(body);

// Save revision to store
DocumentRevision savedRevision = datastore.updateDocumentFromRevision(revision);

データの削除

オブジェクトを削除するには、削除するオブジェクトをストアに渡します。

変更前

Objective-C

// Using an existing store and Automobile
CDTStore *store = existingStore;
Automobile *automobile = existingAutomobile;

// Delete the Automobile object from the store
[store delete:automobile completionHandler:^(NSString *deletedObjectId, NSString *deletedRevisionId, NSError *error) {
    if (error) {
        // delete was not successful, handler received an error
    } else {
        // use the result
        NSLog(@"deleted Automobile doc-%@-rev-%@", deletedObjectId, deletedRevisionId);
    }
}];

Swift

// Using an existing store and Automobile
let store:CDTStore = existingStore
let automobile:Automobile = existingAutomobile

// Delete the Automobile object
store.delete(automobile, completionHandler: { (deletedObjectId:String!, deletedRevisionId:String!, error:NSError!) -> Void in
    if nil != error {
        // delete was not successful, handler received an error
    } else {
        // use the result
        print("deleted document doc-\(deletedObjectId)-rev-\(deletedRevisionId)")
    }
})

Java

// Use an existing store and automobile
Store store = existingStore;
Automobile automobile = existingAutomobile;

// Delete the automobile from the store
Task<String> deleteTask = store.delete(automobile);
deleteTask.continueWith(new Continuation<String, Void>() {
    @Override
    public Void then(Task<String> task) throws Exception {
        if (task.isFaulted()) {
            // delete was not successful, task.getError() contains the error
        } else {
            // use the result
            String deletedAutomobileId = task.getResult();
        }
        return null;
    }
});

変更後

Objective-C

// Use an existing store and revision
CDTDatastore *datastore = existingDatastore;
CDTDocumentRevision *documentRevision = existingDocumentRevision;

// Delete the CDTDocumentRevision from the store
NSError *error = nil;
CDTDocumentRevision *deletedRevision = [datastore deleteDocumentFromRevision:documentRevision error:&error];
if (error) {
    // delete was not successful, handler received an error
} else {
    // use the result
    NSLog(@"deleted document: %@", deletedRevision);
}

Swift

// Use an existing store and revision
let datastore:CDTDatastore = existingDatastore
let documentRevision:CDTDocumentRevision = existingDocumentRevision

var deletedRevision:CDTDocumentRevision?
do{
    deletedRevision = try datastore.deleteDocumentFromRevision(documentRevision)
    NSLog("Revision: \(deletedRevision)");
}catch let error as NSError{
    // Handle error
}

Java

// Use an existing store and revision
Datastore datastore = existingStore;
BasicDocumentRevision documentRevision = (BasicDocumentRevision) existingDocumentRevision;

// Delete revision from store
DocumentRevision deletedRevision = datastore.deleteDocumentFromRevision(documentRevision);

索引の作成

照会を実行するには、索引を作成する必要があります。

  1. データ型が含まれている索引を作成します。データ型が含まれた索引作成は、オブジェクト・マッパーがストアで設定されている場合に役立ちます。

    変更前

    Objective-C

    // Use an existing data store
    CDTStore *store = existingStore;
    
    // The data type to use for the Automobile class
    NSString *dataType = [store.mapper dataTypeForClassName:NSStringFromClass([Automobile class])];
    
    // Create the index
    [store createIndexWithDataType:dataType fields:@[@"year", @"make"] completionHandler:^(NSError *error) {
        if(error){
            // Handle error
        }else{
            // Continue application flow
        }
    }];
    

    Swift

    // A store that has been previously created.
    let store:CDTStore = existingStore
    
    // The data type to use for the Automobile class
    let dataType:String = store.mapper.dataTypeForClassName(NSStringFromClass(Automobile.classForCoder()))
    
    // Create the index
    store.createIndexWithDataType(dataType, fields: ["year","make"]) { (error:NSError!) -> Void in
         if nil != error {
             // Handle error
         } else {
             // Continue application flow
         }
    }
    

    Java

    // Use an existing data store
    Store store = existingStore;
    
    // The data type to use for the Automobile class
    String dataType = store.getMapper().getDataTypeForClassName(Automobile.class.getCanonicalName());
    
    // The fields to index.
    List<IndexField> indexFields = new ArrayList<IndexField>();
    indexFields.add(new IndexField("year"));
    indexFields.add(new IndexField("make"));
    
    // Create the index
    Task<Void> indexTask = store.createIndexWithDataType(dataType, indexFields);
    indexTask.continueWith(new Continuation<Void, Void>() {
         @Override
         public Void then(Task<Void> task) throws Exception {
             if(task.isFaulted()){
                 // Handle error
             }else{
                 // Continue application flow
             }
             return null;
         }
    });
    

    変更後

    Objective-C

    // A store that has been previously created.
    CDTDatastore *datastore = existingDatastore;
    
    NSString *indexName = [datastore ensureIndexed:@[@"@datatype", @"year", @"make"] withName:@"automobileindex"];
    if(!indexName){
         // Handle error
    }
    

    Swift

    // A store that has been previously created.
    let datastore:CDTDatastore = existingDatastore
    
    // Create the index
    let indexName:String? = datastore.ensureIndexed(["@datatype","year","make"], withName: "automobileindex")
    if(indexName == nil){
         // Handle error
    }
    

    Java

    // Use an existing store
    Datastore datastore = existingStore;
    
    // Create an IndexManager
    IndexManager indexManager = new IndexManager(datastore);
    
    // The fields to index.
    List<Object> indexFields = new ArrayList<Object>();
    indexFields.add("@datatype");
    indexFields.add("year");
    indexFields.add("make");
    
    // Create the index
    indexManager.ensureIndexed(indexFields, "automobile_index");
    
  2. 索引を削除します。

    変更前

    Objective-C

    // Use an existing data store
    CDTStore *store = existingStore;
    NSString *indexName = existingIndexName;
    
    // Delete the index
    [store deleteIndexWithName:indexName completionHandler:^(NSError *error) {
         if(error){
             // Handle error
         }else{
             // Continue application flow
         }
    }];
    

    Swift

    // Use an existing store
    let store:CDTStore = existingStore
    
    // The data type to use for the Automobile class
    let dataType:String = store.mapper.dataTypeForClassName(NSStringFromClass(Automobile.classForCoder()))
    
    // Delete the index
    store.deleteIndexWithDataType(dataType, completionHandler: { (error:NSError!) -> Void in
         if nil != error {
             // Handle error
         } else {
             // Continue application flow
         }
    })
    

    Java

    // Use an existing data store
    Store store = existingStore;
    String indexName = existingIndexName;
    
    // Delete the index
    Task<Void> indexTask = store.deleteIndex(indexName);
    indexTask.continueWith(new Continuation<Void, Void>() {
         @Override
         public Void then(Task<Void> task) throws Exception {
             if(task.isFaulted()){
                 // Handle error
             }else{
                 // Continue application flow
             }
             return null;
         }
    });
    

    変更後

    Objective-C

    // Use an existing store
    CDTDatastore *datastore = existingDatastore;
    NSString *indexName = existingIndexName;
    
    // Delete the index
    BOOL success = [datastore deleteIndexNamed:indexName];
    if(!success){
         // Handle error
    }
    

    Swift

    // A store that has been previously created.
    let datastore:CDTDatastore = existingDatastore
    let indexName:String = existingIndexName
    
    // Delete the index
    let success:Bool = datastore.deleteIndexNamed(indexName)
    if(!success){
         // Handle error
    }
    

    Java

    // Use an existing store
    Datastore datastore = existingStore;
    String indexName = existingIndexName;
    IndexManager indexManager = existingIndexManager;
    
    // Delete the index
    indexManager.deleteIndexNamed(indexName);
    

データの照会

索引を作成した後、データベース内のデータを照会できます。

iOS (データの照会)

変更前 (IMFData/CloudantToolkit を使用): iOS (データの照会):

Objective-C

// Use an existing store
CDTStore *store = existingStore;

NSPredicate *queryPredicate = [NSPredicate predicateWithFormat:@"(year = 2006)"];
CDTCloudantQuery *query = [[CDTCloudantQuery alloc] initDataType:[store.mapper dataTypeForClassName:NSStringFromClass([Automobile class])] withPredicate:queryPredicate];

[store performQuery:query completionHandler:^(NSArray *results, NSError *error) {
    if(error){
        // Handle error
    }else{
        // Use result of query.  Result will be Automobile objects.
    }
}];

Swift

// Use an existing store
let store:CDTStore = existingStore

let queryPredicate:NSPredicate = NSPredicate(format:"(year = 2006)")
let query:CDTCloudantQuery = CDTCloudantQuery(dataType: "Automobile", withPredicate: queryPredicate)

store.performQuery(query, completionHandler: { (results:[AnyObject]!, error:NSError!) -> Void in
    if nil != error {
        // Handle error
    } else {
        // Use result of query.  Result will be Automobile objects.
    }
})
変更後 (Cloudant Sync を使用) (データの照会):

Objective-C

// Use an existing store
CDTDatastore *datastore = existingDatastore;

CDTQResultSet *results = [datastore find:@{@"@datatype" : @"Automobile", @"year" : @2006}];
if(results){
    // Use results
}
// Use an existing store
let datastore:CDTDatastore = existingDatastore

let results:CDTQResultSet? = datastore.find(["@datatype" : "Automobile", "year" : 2006])
if(results == nil){
    // Handle error
}

Android (データの照会)

オブジェクトの照会を実行するには、データ・タイプに対して照会フィルターを使用して Cloudant 照会を作成します。Store オブジェクトに対して照会を実行します。

変更前 (IMFData/CloudantToolkit を使用): Android (データの照会):
// Use an existing store
Store store = existingStore;

// Create data type predicate
Map<String, Object> dataTypeEqualityOpMap = new HashMap<String, Object>();
dataTypeEqualityOpMap.put("$eq", "Automobile");

Map<String, Object> dataTypeSelectorMap = new HashMap<String, Object>();
dataTypeSelectorMap.put("@datatype", dataTypeEqualityOpMap);

// Create year predicate
Map<String, Object> yearEqualityOpMap = new HashMap<String, Object>();
yearEqualityOpMap.put("$eq", 2006);

Map<String, Object> yearSelectorMap = new HashMap<String, Object>();
yearSelectorMap.put("year", yearEqualityOpMap);

// Add predicates to AND compound predicate
List<Map<String, Object>> andPredicates = new ArrayList<Map<String, Object>>();
andPredicates.add(dataTypeSelectorMap);
andPredicates.add(yearSelectorMap);

Map<String, Object> andOpMap = new HashMap<String, Object>();
andOpMap.put("$and", andPredicates);

Map<String, Object> cloudantQueryMap = new HashMap<String, Object>();
cloudantQueryMap.put("selector", andOpMap);

// Create a Cloudant Query Object
CloudantQuery query = new CloudantQuery(cloudantQueryMap);

// Run the Cloudant Query against a Store
Task<List> queryTask = store.performQuery(query);
queryTask.continueWith(new Continuation<List, Object>() {
    @Override
    public Object then(Task<List> task) throws Exception {
        if(task.isFaulted()){
            // Handle Error
        }else{
            List queryResult = task.getResult();
            // Use queryResult to do something
        }
        return null;
    }
});
変更後 (Cloudant Sync を使用): Android (データの照会):
// Use an existing store
Datastore datastore = existingStore;
IndexManager indexManager = existingIndexManager;

// Create data type predicate
Map<String, Object> dataTypeEqualityOpMap = new HashMap<String, Object>();
dataTypeEqualityOpMap.put("$eq", "Automobile");

Map<String, Object> dataTypeSelectorMap = new HashMap<String, Object>();
dataTypeSelectorMap.put("@datatype", dataTypeEqualityOpMap);

// Create year predicate
Map<String, Object> yearEqualityOpMap = new HashMap<String, Object>();
yearEqualityOpMap.put("$eq", 2006);

Map<String, Object> yearSelectorMap = new HashMap<String, Object>();
yearSelectorMap.put("year", yearEqualityOpMap);

// Add predicates to AND compound predicate
List<Map<String, Object>> andPredicates = new ArrayList<Map<String, Object>>();
andPredicates.add(dataTypeSelectorMap);
andPredicates.add(yearSelectorMap);

Map<String, Object> selectorMap = new HashMap<String, Object>();
selectorMap.put("$and", andPredicates);

// Run the query against a Store
QueryResult result = indexManager.find(selectorMap);

オフライン・ストレージおよび同期のサポート

モバイル・デバイス上のデータをリモート・データベース・インスタンスと同期できます。リモート・データベースの更新をモバイル・デバイス上のローカル・データベースにプルするか、ローカル・データベースの更新をリモート・データベースにプッシュできます。

プル複製の実行

変更前

Objective-C

// store is an existing CDTStore object created using IMFDataManager remoteStore
__block NSError *replicationError;
CDTPullReplication *pull = [manager pullReplicationForStore: store.name];
CDTReplicator *replicator = [manager.replicatorFactory oneWay:pull error:&replicationError];
if(replicationError){
    // Handle error
}else{
    // replicator creation was successful
}

[replicator startWithError:&replicationError];
if(replicationError){
    // Handle error
}else{
    // replicator start was successful
}

// (optionally) monitor replication via polling
while (replicator.isActive) {
    [NSThread sleepForTimeInterval:1.0f];
    NSLog(@"replicator state : %@", [CDTReplicator stringForReplicatorState:replicator.state]);
}

Swift

// Use an existing store
let store:CDTStore = existingStore

do {
    // store is an existing CDTStore object created using IMFDataManager remoteStore
    let pull:CDTPullReplication = manager.pullReplicationForStore(store.name)
    let replicator:CDTReplicator = try manager.replicatorFactory.oneWay(pull)
    
    // start replication
    try replicator.start()

    // (optionally) monitor replication via polling
    while replicator.isActive() {
        NSThread.sleepForTimeInterval(1.0)
        print("replicator state : \(CDTReplicator.stringForReplicatorState(replicator.state))")
    }

} catch let error as NSError {
    // Handle error
}

Java

// Use an existing store
Store store = existingStore;

// create a pull replication task
// name is the database name of the store being replicated
Task<PullReplication> pullTask = manager.pullReplicationForStore(store.getName());
pullTask.continueWith(new Continuation<PullReplication, Object>() {
    @Override
    public Object then(Task<PullReplication> task) throws Exception {
        if(task.isFaulted()){
            // Handle error
        }else{
            // Start the replication
            PullReplication pull = task.getResult();
            Replicator replicator = ReplicatorFactory.oneway(pull);
            replicator.start();
        }
        return null;
    } 
});

変更後

Objective-C

// Use an existing datastore
NSURL *remoteStoreUrl = existingRemoteStoreUrl;
CDTDatastoreManager *datastoreManager = existingDatastoreManager;
CDTDatastore *datastore = existingDatastore;

// Create pull replication objects
__block NSError *replicationError;
CDTReplicatorFactory *replicatorFactory = [[CDTReplicatorFactory alloc]initWithDatastoreManager:datastoreManager];
CDTPullReplication *pull = [CDTPullReplication replicationWithSource:remoteStoreUrl target:datastore];
CDTReplicator *replicator = [replicatorFactory oneWay:pull error:&error];
if(replicationError){
    // Handle error
}else{
    // replicator creation was successful
}

[replicator startWithError:&replicationError];
if(replicationError){
    // Handle error
}else{
    // replicator start was successful
}

// (optionally) monitor replication via polling
while (replicator.isActive) {
    [NSThread sleepForTimeInterval:1.0f];
    NSLog(@"replicator state : %@", [CDTReplicator stringForReplicatorState:replicator.state]);
}

Swift

let remoteStoreUrl:NSURL = existingRemoteStoreUrl
let datastoreManager:CDTDatastoreManager = existingDatastoreManager
let datastore:CDTDatastore = existingDatastore


do {
    // store is an existing CDTStore object created using IMFDataManager remoteStore
    let replicatorFactory = CDTReplicatorFactory(datastoreManager: datastoreManager)
    let pull:CDTPullReplication = CDTPullReplication(source: remoteStoreUrl, target: datastore)
    let replicator:CDTReplicator = try replicatorFactory.oneWay(pull)

    // start replication
    try replicator.start()

    // (optionally) monitor replication via polling
    while replicator.isActive() {
        NSThread.sleepForTimeInterval(1.0)
        print("replicator state : \(CDTReplicator.stringForReplicatorState(replicator.state))")
    }

} catch let error as NSError {
    // Handle error
}

Java

// Use an opened Datastore to replicate to
Datastore datastore = existingDatastore;
URI uri = existingURI;

// Create a replicator that replicates changes from the remote
final Replicator replicator = ReplicatorBuilder.pull().from(uri).to(datastore).build();

// Register event listener
replicator.getEventBus().register(new Object() {

    @Subscribe
    public void complete(ReplicationCompleted event) {

        // Handle ReplicationCompleted event
    }

    @Subscribe
    public void error(ReplicationErrored event) {

        // Handle ReplicationErrored event
    }
});

// Start replication
replicator.start();

プッシュ複製の実行

変更前

Objective-C

/ store is an existing CDTStore object created using IMFDataManager localStore
__block NSError *replicationError;
CDTPushReplication *push = [manager pushReplicationForStore: store.name];
CDTReplicator *replicator = [manager.replicatorFactory oneWay:push error:&replicationError];
if(replicationError){
    // Handle error
}else{
    // replicator creation was successful
}

[replicator startWithError:&replicationError];
if(replicationError){
    // Handle error
}else{
    // replicator start was successful
}

// (optionally) monitor replication via polling
while (replicator.isActive) {
    [NSThread sleepForTimeInterval:1.0f];
    NSLog(@"replicator state : %@", [CDTReplicator stringForReplicatorState:replicator.state]);
}

Swift

// Use an existing store
let store:CDTStore = existingStore

do {
    // store is an existing CDTStore object created using IMFDataManager localStore
    let push:CDTPushReplication = manager.pushReplicationForStore(store.name)
    let replicator:CDTReplicator = try manager.replicatorFactory.oneWay(push)
    
    // Start replication
    try replicator.start()

    // (optionally) monitor replication via polling
    while replicator.isActive() {
        NSThread.sleepForTimeInterval(1.0)
        print("replicator state : \(CDTReplicator.stringForReplicatorState(replicator.state))")
    }
} catch let error as NSError {
    // Handle error
}

Java

// Use an existing store
Store store = existingStore;

// create a push replication task
// name is the database name of the store being replicated
Task<PushReplication> pushTask = manager.pushReplicationForStore(store.getName());
pushTask.continueWith(new Continuation<PushReplication, Object>() {
    @Override
    public Object then(Task<PushReplication> task) throws Exception {
        if(task.isFaulted()){
            // Handle error
        }else{
            // Start the replication
            PushReplication push = task.getResult();
            Replicator replicator = ReplicatorFactory.oneway(push);
            replicator.start();
        }
        return null;
    }
});

変更後

Objective-C

// Use an existing datastore
NSURL *remoteStoreUrl = existingRemoteStoreUrl;
CDTDatastoreManager *datastoreManager = existingDatastoreManager;
CDTDatastore *datastore = existingDatastore;

// Create push replication objects
__block NSError *replicationError;
CDTReplicatorFactory *replicatorFactory = [[CDTReplicatorFactory alloc]initWithDatastoreManager:datastoreManager];
CDTPushReplication *push = [CDTPushReplication replicationWithSource:datastore target:remoteStoreUrl];
CDTReplicator *replicator = [replicatorFactory oneWay:push error:&error];
if(replicationError){
    // Handle error
}else{
    // replicator creation was successful
}

[replicator startWithError:&replicationError];
if(replicationError){
    // Handle error
}else{
    // replicator start was successful
}

// (optionally) monitor replication via polling
while (replicator.isActive) {
    [NSThread sleepForTimeInterval:1.0f];
    NSLog(@"replicator state : %@", [CDTReplicator stringForReplicatorState:replicator.state]);
}

Swift

let remoteStoreUrl:NSURL = existingRemoteStoreUrl
let datastoreManager:CDTDatastoreManager = existingDatastoreManager
let datastore:CDTDatastore = existingDatastore


do {
    // store is an existing CDTStore object created using IMFDataManager remoteStore
    let replicatorFactory = CDTReplicatorFactory(datastoreManager: datastoreManager)
    let push:CDTPushReplication = CDTPushReplication(source: datastore, target: remoteStoreUrl)
    let replicator:CDTReplicator = try replicatorFactory.oneWay(push)
    
    // start replication
    try replicator.start()

    // (optionally) monitor replication via polling
    while replicator.isActive() {
        NSThread.sleepForTimeInterval(1.0)
        print("replicator state : \(CDTReplicator.stringForReplicatorState(replicator.state))")
    }

} catch let error as NSError {
    // Handle error
}

Java

// Use an opened Datastore to replicate from
Datastore datastore = existingStore;
URI uri = existingURI;

// Create a replicator that replicates changes from the local
// database to the remote datastore.
final Replicator replicator = ReplicatorBuilder.push().from(datastore).to(uri).build();

// Register event listener
replicator.getEventBus().register(new Object() {

    @Subscribe
    public void complete(ReplicationCompleted event) {

        // Handle ReplicationCompleted event
    }

    @Subscribe
    public void error(ReplicationErrored event) {

        // Handle ReplicationErrored event
    }
});

// Start replication
replicator.start();
Last modified on August 23, 2017