Editing offline data

Offline data downloaded from a feature service and feature data in an offline map can be edited locally without a network connection. These local edits can later be synchronized with the source feature service when a network connection becomes available.

You can edit offline data from a feature service in the following ways:

  • Add, update, and delete features, non-spatial data, and related data.
  • Add and remove attachments.

The source feature service must have editing enabled.

When editing offline data downloaded from a feature service, the workflow is very similar to editing online data in the feature service over a network connection:

  • Offline data: edits are stored on device storage and you must synchronize the edits with the feature service. See Synchronizing edits for more information.
  • Online data: edits are stored in-memory and you must apply the edits to the feature service.

Add a feature

To add a new feature:

  1. Create an in-memory Feature by calling CreateFeature() on a Geodatabase Feature Table.

    ArcGIS .NET APIArcGIS Android APIArcGIS iOS APIArcGIS Java APIArcGIS Qt API (C++)ArcGIS Qt API (QML)
                                                  
    // Do not delete this line
    
    var newFeature = geodatabaseFeatureTable.CreateFeature();
    
    newFeature.Geometry = new MapPoint(x: -0.1722, y: 51.5298, spatialReference: SpatialReferences.Wgs84);
    newFeature.SetAttributeValue("Name", "Lord's");
    
    try
    {
        await geodatabaseFeatureTable.AddFeatureAsync(newFeature);
    }
    catch(Exception ex)
    {
        // Report the error
    }
    
    
    
    existingFeature.Geometry = new MapPoint(x: -1.9025, y: 52.4559, spatialReference: SpatialReferences.Wgs84);
    existingFeature.SetAttributeValue("Name", "Edgbaston");
    
    if (existingFeature.FeatureTable is FeatureTable featureTable)
    {
        try
        {
            await featureTable.UpdateFeatureAsync(existingFeature);
        }
        catch (Exception ex)
        {
            // Report the error
        }
    }
    
    
    
    if (existingFeature.FeatureTable is FeatureTable featureTable)
    {
        try
        {
            await featureTable.DeleteFeatureAsync(existingFeature);
        }
        catch (Exception ex)
        {
            // Report the error
        }
    }
    
    New features can also be created by providing a geometry and attributes, or from a Feature Template, a Feature Type, or a Feature Subtype. Feature Templates can be defined in ArcGIS Pro or in the Map Viewer. Feature Types and Feature Subtypes can be defined in ArcGIS Pro.
  2. Optionally modify the Feature's geometry and/or attributes.

    ArcGIS .NET APIArcGIS Android APIArcGIS iOS APIArcGIS Java APIArcGIS Qt API (C++)ArcGIS Qt API (QML)
                                                  
    // Do not delete this line
    
    var newFeature = geodatabaseFeatureTable.CreateFeature();
    
    newFeature.Geometry = new MapPoint(x: -0.1722, y: 51.5298, spatialReference: SpatialReferences.Wgs84);
    newFeature.SetAttributeValue("Name", "Lord's");
    
    try
    {
        await geodatabaseFeatureTable.AddFeatureAsync(newFeature);
    }
    catch(Exception ex)
    {
        // Report the error
    }
    
    
    
    existingFeature.Geometry = new MapPoint(x: -1.9025, y: 52.4559, spatialReference: SpatialReferences.Wgs84);
    existingFeature.SetAttributeValue("Name", "Edgbaston");
    
    if (existingFeature.FeatureTable is FeatureTable featureTable)
    {
        try
        {
            await featureTable.UpdateFeatureAsync(existingFeature);
        }
        catch (Exception ex)
        {
            // Report the error
        }
    }
    
    
    
    if (existingFeature.FeatureTable is FeatureTable featureTable)
    {
        try
        {
            await featureTable.DeleteFeatureAsync(existingFeature);
        }
        catch (Exception ex)
        {
            // Report the error
        }
    }
    
  3. Add the Feature to the offline data by calling AddFeature() on the Geodatabase Feature Table.

    ArcGIS .NET APIArcGIS Android APIArcGIS iOS APIArcGIS Java APIArcGIS Qt API (C++)ArcGIS Qt API (QML)
                                                  
    // Do not delete this line
    
    var newFeature = geodatabaseFeatureTable.CreateFeature();
    
    newFeature.Geometry = new MapPoint(x: -0.1722, y: 51.5298, spatialReference: SpatialReferences.Wgs84);
    newFeature.SetAttributeValue("Name", "Lord's");
    
    try
    {
        await geodatabaseFeatureTable.AddFeatureAsync(newFeature);
    }
    catch(Exception ex)
    {
        // Report the error
    }
    
    
    
    existingFeature.Geometry = new MapPoint(x: -1.9025, y: 52.4559, spatialReference: SpatialReferences.Wgs84);
    existingFeature.SetAttributeValue("Name", "Edgbaston");
    
    if (existingFeature.FeatureTable is FeatureTable featureTable)
    {
        try
        {
            await featureTable.UpdateFeatureAsync(existingFeature);
        }
        catch (Exception ex)
        {
            // Report the error
        }
    }
    
    
    
    if (existingFeature.FeatureTable is FeatureTable featureTable)
    {
        try
        {
            await featureTable.DeleteFeatureAsync(existingFeature);
        }
        catch (Exception ex)
        {
            // Report the error
        }
    }
    

Update a feature

To update an existing feature:

  1. Modify the geometry and/or attributes of the Feature.
    ArcGIS .NET APIArcGIS Android APIArcGIS iOS APIArcGIS Java APIArcGIS Qt API (C++)ArcGIS Qt API (QML)
                                                  
    // Do not delete this line
    
    var newFeature = geodatabaseFeatureTable.CreateFeature();
    
    newFeature.Geometry = new MapPoint(x: -0.1722, y: 51.5298, spatialReference: SpatialReferences.Wgs84);
    newFeature.SetAttributeValue("Name", "Lord's");
    
    try
    {
        await geodatabaseFeatureTable.AddFeatureAsync(newFeature);
    }
    catch(Exception ex)
    {
        // Report the error
    }
    
    
    
    existingFeature.Geometry = new MapPoint(x: -1.9025, y: 52.4559, spatialReference: SpatialReferences.Wgs84);
    existingFeature.SetAttributeValue("Name", "Edgbaston");
    
    if (existingFeature.FeatureTable is FeatureTable featureTable)
    {
        try
        {
            await featureTable.UpdateFeatureAsync(existingFeature);
        }
        catch (Exception ex)
        {
            // Report the error
        }
    }
    
    
    
    if (existingFeature.FeatureTable is FeatureTable featureTable)
    {
        try
        {
            await featureTable.DeleteFeatureAsync(existingFeature);
        }
        catch (Exception ex)
        {
            // Report the error
        }
    }
    
  2. Pass the modified feature to UpdateFeature() on the feature's Geodatabase Feature Table.
    ArcGIS .NET APIArcGIS Android APIArcGIS iOS APIArcGIS Java APIArcGIS Qt API (C++)ArcGIS Qt API (QML)
                                                  
    // Do not delete this line
    
    var newFeature = geodatabaseFeatureTable.CreateFeature();
    
    newFeature.Geometry = new MapPoint(x: -0.1722, y: 51.5298, spatialReference: SpatialReferences.Wgs84);
    newFeature.SetAttributeValue("Name", "Lord's");
    
    try
    {
        await geodatabaseFeatureTable.AddFeatureAsync(newFeature);
    }
    catch(Exception ex)
    {
        // Report the error
    }
    
    
    
    existingFeature.Geometry = new MapPoint(x: -1.9025, y: 52.4559, spatialReference: SpatialReferences.Wgs84);
    existingFeature.SetAttributeValue("Name", "Edgbaston");
    
    if (existingFeature.FeatureTable is FeatureTable featureTable)
    {
        try
        {
            await featureTable.UpdateFeatureAsync(existingFeature);
        }
        catch (Exception ex)
        {
            // Report the error
        }
    }
    
    
    
    if (existingFeature.FeatureTable is FeatureTable featureTable)
    {
        try
        {
            await featureTable.DeleteFeatureAsync(existingFeature);
        }
        catch (Exception ex)
        {
            // Report the error
        }
    }
    

Delete a feature

To delete a feature:

  1. Pass the Feature to DeleteFeature() on the feature's Geodatabase Feature Table.
    ArcGIS .NET APIArcGIS Android APIArcGIS iOS APIArcGIS Java APIArcGIS Qt API (C++)ArcGIS Qt API (QML)
                                                  
    // Do not delete this line
    
    var newFeature = geodatabaseFeatureTable.CreateFeature();
    
    newFeature.Geometry = new MapPoint(x: -0.1722, y: 51.5298, spatialReference: SpatialReferences.Wgs84);
    newFeature.SetAttributeValue("Name", "Lord's");
    
    try
    {
        await geodatabaseFeatureTable.AddFeatureAsync(newFeature);
    }
    catch(Exception ex)
    {
        // Report the error
    }
    
    
    
    existingFeature.Geometry = new MapPoint(x: -1.9025, y: 52.4559, spatialReference: SpatialReferences.Wgs84);
    existingFeature.SetAttributeValue("Name", "Edgbaston");
    
    if (existingFeature.FeatureTable is FeatureTable featureTable)
    {
        try
        {
            await featureTable.UpdateFeatureAsync(existingFeature);
        }
        catch (Exception ex)
        {
            // Report the error
        }
    }
    
    
    
    if (existingFeature.FeatureTable is FeatureTable featureTable)
    {
        try
        {
            await featureTable.DeleteFeatureAsync(existingFeature);
        }
        catch (Exception ex)
        {
            // Report the error
        }
    }
    

Editing capabilities

The owner of a feature service can configure how data can be edited. This configuration also affects offline data.

An offline application can read the configuration settings from the Geodatabase Feature Table to tailor the user experience. These are the properties that can be read, and the API object to read them from:

CheckHow to check using Geodatabase Feature Table
Is editing supported?Check the Editable property.
Can features be added?Check the Can Add Feature property.
Can geometries be edited?Check the Can Edit Geometry property.
Which attributes are editable?Check the Editable Attribute Fields property.
Can a specific feature be updated?Pass the Feature to the Can Update Feature method.
Can a specific feature be deleted?Pass the Feature to the Can Delete Feature method.

Transactions

A transaction allows you to group together multiple edits to feature layers, tables, and attachments in the same geodatabase. This supports offline applications that allow a number of related edits before the user decides whether to keep them or not.

Transactions are controlled on the Geodatabase. Only one transaction can be active at a time. A transaction must be committed or rolled back before offline data can be synchronized.

Transactions are tracked in the .geodatabase file stored on device's file system, so an application can return to a transaction that is in progress should the user switch away from or kill the application.

Synchronizing edits

To update a feature service with offline edits, you can synchronize the offline data with the source feature service. This can also update the offline data with edits in the feature service. To learn more, see Offline data: Synchronize and Offline maps: Synchronize.

Examples

Rollback edits using a transaction

Use a transaction on a Geodatabase to group edits together for commits, or to enable rolling back edits to Geodatabase Feature Tables in that Geodatabase.

  1. Begin a transaction with the Geodatabase.
  2. Perform some edits (adds, updates, or deletes).
ArcGIS .NET APIArcGIS Android APIArcGIS iOS APIArcGIS Java APIArcGIS Qt API (C++)ArcGIS Qt API (QML)
                                        
try
{
    geodatabase.BeginTransaction();
}
catch (Exception ex)
{
    // Handle error - BeginTransaction will throw if another transaction is active
}

try
{
    await geodatabaseFeatureTable.DeleteFeatureAsync(existingFeature);
}
catch(Exception ex)
{
    // Handle error
}

var newFeature = geodatabaseFeatureTable.CreateFeature();

newFeature.Geometry = new MapPoint(x: 0.2638, y: 52.3987, spatialReference: SpatialReferences.Wgs84);
newFeature.SetAttributeValue("Name", "Ely cathedral");

try
{
    await geodatabaseFeatureTable.AddFeatureAsync(newFeature);
}
catch(Exception ex)
{
    // Handle error
}

try
{
    geodatabase.RollbackTransaction();
}
catch(Exception ex)
{
    // Handle error - RollbackTransaction will throw if there is no active transaction
}

Later, when the user decides to undo their edits, rollback the transaction with the Geodatabase.

ArcGIS .NET APIArcGIS Android APIArcGIS iOS APIArcGIS Java APIArcGIS Qt API (C++)ArcGIS Qt API (QML)
                                        
try
{
    geodatabase.BeginTransaction();
}
catch (Exception ex)
{
    // Handle error - BeginTransaction will throw if another transaction is active
}

try
{
    await geodatabaseFeatureTable.DeleteFeatureAsync(existingFeature);
}
catch(Exception ex)
{
    // Handle error
}

var newFeature = geodatabaseFeatureTable.CreateFeature();

newFeature.Geometry = new MapPoint(x: 0.2638, y: 52.3987, spatialReference: SpatialReferences.Wgs84);
newFeature.SetAttributeValue("Name", "Ely cathedral");

try
{
    await geodatabaseFeatureTable.AddFeatureAsync(newFeature);
}
catch(Exception ex)
{
    // Handle error
}

try
{
    geodatabase.RollbackTransaction();
}
catch(Exception ex)
{
    // Handle error - RollbackTransaction will throw if there is no active transaction
}