For up-to-date product documentation, see the IBM MobileFirst Foundation Developer Center.


Supporting offline storage and synchronization

We can synchronize the data on a mobile device with a remote database instance. You can either pull updates from a remote database to the local database on the mobile device, or push local database updates to a remote database.


Before you begin

For more details, see CDTDatastore Replication documentation.

AndroidFor more details, see Cloudant® Sync Replication documentation. For CRUD operations on a remote store, see the Cloudant Replication API

Parent topic: Migrating apps storing mobile data in Cloudant with IMFData or Cloudant SDK


Running pull replication


Procedure

Run pull replication.

BEFORE (with IMFData/CloudantToolkit):

// 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]); }

// 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 } Android

// 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; } });

AFTER (with Cloudant Sync):

// 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]); }

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 } Android

// 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();


Running push replication


Procedure

Run push replication.

BEFORE (with IMFData/CloudantToolkit):

// 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]); }

// 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 } Android

// 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; } });

AFTER (with Cloudant Sync):

// 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]); }

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 } Android

// 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();