Syncing Up
To apply local changes on the server, use one of the “sync up” methods. These methods update the server with data from the given SmartStore soup. They look for created, updated, or deleted records in the soup, and then replicate those changes on the server. The options
argument specifies a list of fields to be updated. In Mobile SDK5.1 and later, you can override this field list by initializing the sync manager object with separate field lists for create and update operations. See Handling Field Lists in Create and Update Operations .
Locally created objects must include an “attributes” field that contains a “type” field that specifies the sObject type. For example, for an account named Acme, use: {Id:”local_x”, Name: Acme, attributes: {type:”Account”}}
.
-
You can create a named sync without running it.
- Swift
- Objective-C
-
You can create and run a sync with just options that uses the default target.
- Swift
- Objective-C
-
You can create and run a sync based on a target that you configure in code.
- Swift
- Objective-C
-
Or, you can create and run a named sync. If you load a sync with the same name from a configuration file, this sync overrides it.
- Swift
- Objective-C
-
To run or rerun an existing named sync configuration:
- Swift
- Objective-C
-
Or, to rerun a previous sync operation by sync ID:
- Swift
- Objective-C
-
To rerun a sync without getting progress updates, use this function from the Mobile Sync Swift extension:
- Swift
- Objective-C
(Not available.)
-
To sync up by external ID, see Syncing Up by External ID.
-
You can create a named sync up configuration without running it.
-
You can create and run an unnamed sync up configuration:
-
You can create and run a named sync up configuration:
-
To run or rerun an existing named sync configuration:
-
Or, to rerun a previous sync operation by sync ID:
-
To sync up by external ID, see Syncing Up by External ID.
For sync up operations, you can specify a mergeMode option. You can choose one of the following behaviors:
-
Overwrite server records even if they've changed since they were synced down to that client. When you call the
syncUp
method:-
iOS: Set the options parameter to
- Swift
- Objective-C
[SFSyncOptions newSyncOptionsForSyncUp: ["Name"], mergeMode:SFSyncStateMergeModeOverwrite]
-
Android: Set the options parameter to
SSyncOptions.optionsForSyncUp(fieldlist, SyncState.MergeMode.OVERWRITE)
-
Hybrid: Set the syncOptions parameter to
{mergeMode:"OVERWRITE"}
-
-
If any server record has changed since it was synced down to that client, leave it in its current state. The corresponding client record also remains in its current state. When you call the
syncUp()
method:-
iOS: Set the options parameter to
- Swift
- Objective-C
[SFSyncOptions newSyncOptionsForSyncUp:fieldlist mergeMode:SFSyncStateMergeModeLeaveIfChanged]
-
Android: Set the options parameter to
SyncOptions.optionsForSyncUp(fieldlist, SyncState.MergeMode.LEAVE_IF_CHANGED)
-
Hybrid: Set the
syncOptions
parameter to{mergeMode:"LEAVE_IF_CHANGED"}
-
If your local record includes the target’s modification date field, Mobile SDK detects changes by comparing it to the server record’s matching field. The default modification date field is lastModifiedDate
. If your local records do not include the modification date field, the LEAVE_IF_CHANGED
sync up operation reverts to an overwrite sync up.
The LEAVE_IF_CHANGED
merge requires extra round trips to the server. More importantly, the status check and the record save operations happen in two successive calls. In rare cases, a record that is updated between these calls can be prematurely modified on the server.
The MobileSyncExplorerSwift sample app demonstrates how to use named syncs and sync configuration files with the Salesforce Contact object. In iOS, this sample defines a ContactSObjectData
class that represents a contact record as a Swift object. The sample also defines several support classes:
ContactSObjectDataSpec
SObjectData
SObjectDataSpec
SObjectDataFieldSpec
SObjectDataManager
To sync Contact data with the SmartStore soup, this app defines the following named sync operations in the Resources/usersyncs.json
file:
In the RootViewController
class, the syncUpDown()
method starts the flow by calling the updateRemoteData(_:onFailure:)
method of SObjectDataManager
.
For the first argument of updateRemoteData
, which represents success, syncUpDown
passes a block that calls the refreshList()
method of RootViewController
. This method filters the local contacts according to customer input and refreshes the view.
updateRemoteData
calls reSync
using the syncUpContacts
model—aliased here as kSyncUpName
—. Syncing up ensures that allowed soup changes are merged into the Salesforce org.
If sync up succeeds—that is, if the SyncState
status indicates “done”—several things happen:
-
queryLocalData
retrieves all raw data from the freshly updated soup. -
populateDataRows
transforms the soup’s data toContactSObjectData
objects and stores these objects in an internal array. -
Control passes to
refreshRemoteData(_:onFailure:)
. TherefreshRemoteData
method looks similar toupdateRemoteData
with two exceptions:- It performs a sync down instead of sync up.
- If sync down succeeds, it “closes the circle” by executing the block that’s been passed to it from
syncUpDown
viaupdateRemoteData
.
To summarize everything that happens in the syncUpDown
call stack:
- Sync up: It syncs soup changes up to the server by calling
updateRemoteData
onSObjectsDataManager
. This step ensures that all allowable local and offline changes are merged into Salesforce. - Sync down: After the soup records are merged with server data, it syncs server data down to the soup through a call to
refreshRemoteData
. This step ensures that the soup reflects changes originating on the server and also changes merged from sync up. Remember: The sync up merge mode determines which soup edits are allowed on the server. - Finally, it updates its UI with the updated contact records from the soup.
When you’re syncing records, always apply a sync up-sync down pair in the sequence demonstrated by the MobileSyncExplorerSwift sample app.
If the update block provided here determines that the sync operation has finished, it calls the completion block that’s passed into updateRemoteData
. A user initiates a syncing operation by tapping a button. Therefore, to see the definition of the completion block, look at the syncUpDown
button handler in ContactListViewController.m
. The handler calls updateRemoteData
with the following block.
If the sync up operation succeeded, this block first refreshes the display on the device, along with a “Sync complete!” confirmation toast. Regardless of the status of the sync operation, this method refreshes local and remote data. This step covers partial successes and completions.
To sync up to the server, you call syncUp()
with the same arguments as syncDown()
: list of fields, name of source SmartStore soup, and an update callback. The only coding difference is that you can format the list of affected fields as an instance of SyncOptions
instead of SyncTarget
. Here’s the way it’s handled in the MobileSyncExplorer sample:
In the internal SyncUpdateCallback
implementation, this example takes the extra step of calling syncDown()
when sync up is done. This step guarantees that the SmartStore soup remains up-to-date with any recent changes made to Contacts on the server.