Your users can edit offline in a services pattern and later sync their edits back to a feature service when connected. Syncing offline edits requires that you've created a geodatabase using a sync-enabled feature service from ArcGIS for Server, ArcGIS Online, or Portal for ArcGIS, as described in Create an offline map. After users have made edits and are ready to sync their local copy of the data with the service, use GeodatabaseSyncTask to sync with the feature service. Syncing can be performed even if no edits have been made locally, to pull changes from the feature service into the local copy of the data.
To synchronize edits, do the following:
- Create a System.IProgress object to report changes in the synchronization task status.
- Set up a callback to report when the process finishes or fails.
- Create or obtain sync parameters for the synchronization task.
- Create a GeodatabaseSyncTask instance.
- Call the SyncGeodatabaseAsync method on the GeodatabaseSyncTask using the callbacks and sync parameters you set up.
Note:In a sync operation, edits most recently synced to the service will overwrite previously synced edits, regardless of time of edits.
For descriptions of errors that can arise when syncing offline edits, see Error handling with sync.
Register a geodatabase in a pre-planned workflow
In a services pattern workflow known as a pre-planned workflow, you generate the geodatabase once and load copies of it onto each user's device. If you've generated the geodatabase on the user's device with , you don't need to register a geodatabase.
In the pre-planned workflow, you use the RegisterGeodatabaseAsync method to register each geodatabase copy (on each device) with the feature service you used to generate the original geodatabase. Registering in this way ensures each device receives the correct updates during sync operations.
- Once you call unregister on a geodatabase, you cannot re-register the same geodatabase.
- If the original geodatabase is ever unregistered, no additional clients can use that copy to register.
For a list of benefits of this workflow, see Register a geodatabase in a pre-planned workflow in "Create an offline map."
The following sample shows how to sync your offline edits back to a feature service.
// private variable to track cancellation requests
private CancellationTokenSource _syncCancellationTokenSource;
// callback for when the synchronization completes or fails ...
private void syncCompleteCallback(GeodatabaseStatusInfo statusInfo, Exception ex)
// reset the cancellation token source
_syncCancellationTokenSource = null;
// if unsuccessful, report the exception and return
if (ex != null)
this.ReportStatus("An exception occured: " + ex.Message);
// if successful, notify the user
this.ReportStatus("Synchronization of '" + statusInfo.GeodatabaseName + "' is complete.");
// optionally, do something with the result
var resultUri = statusInfo.ResultUri;
// function to submit a sync task
// -the url for the feature service and the path to the local geodatabase are passed in
public async Task SyncronizeEditsAsync(string serviceUrl, string geodatabasePath)
// create sync parameters
var taskParameters = new SyncGeodatabaseParameters()
RollbackOnFailure = true,
SyncDirection = Esri.ArcGISRuntime.Tasks.Offline.SyncDirection.Bidirectional
// cancel if an earlier call was made and hasn't completed
if (_syncCancellationTokenSource != null)
// create a new cancellation token
_syncCancellationTokenSource = new CancellationTokenSource();
var cancelToken = _syncCancellationTokenSource.Token;
// create a sync task with the url of the feature service to sync
var syncTask = new GeodatabaseSyncTask(new Uri(serviceUrl));
// open the local geodatabase
var gdb = await Esri.ArcGISRuntime.Data.Geodatabase.OpenAsync(geodatabasePath);
// create a new Progress object to report updates to the sync status
var progress = new Progress<GeodatabaseStatusInfo>();
progress.ProgressChanged += (sender, s) =>
// call SyncGeodatabaseAsync and pass in: sync params, local geodatabase, completion callback, update interval, progress, and cancellation token
var gdbResult = await syncTask.SyncGeodatabaseAsync(