Create an offline layer

Taking individual layers offline allows you to build apps that can operate without network connectivity. Your users will be able to continue viewing maps, navigating to locations, query and identify features, edit data and synchronize it when connectivity returns. You can choose to take a whole map and all of its layers offline but taking individual layers offline gives you more granular control. You can decide when and how individual offline layers are created, used and synchronized within your app.

Use either the Services pattern or the Desktop pattern to take layers offline. With the Services pattern you can use this API to download tile and feature data to your device from any ArcGIS Online or ArcGIS Enterprise service (as long as the service is enabled for offline use). With the Desktop pattern you can author packages in ArcGIS Pro or create local data sources, such as mobile geodatabases, shapefiles, GeoPackages, and tile caches, and sideload them onto your devices.

Services pattern

If your users need to access up-to-date information we recommend that you adopt the Services pattern to take your layer offline from ArcGIS Online or ArcGIS Enterprise services. This pattern allows you to build apps that can download either feature and tiled data directly to your device, whenever network connectivity is available.

To obtain offline feature data you will create and download a specific geographical area from a sync-enabled feature services into a mobile geodatabase. If you edit this feature data you can control whether the edits are uploaded, other users edits are downloaded, or both whenever connectivity is restored. This synchronization process allows the app to maintain an up-to-date view of the feature data.

For tiled data, you can create either raster and vector tile caches from your own data or from ESRI's export enabled basemaps, as follows:

You can export, download, and store these caches locally as packages and access them whilst your device is offline. You cannot edit this data and if you require updates to the data you will need to export and download them again.

Feature layers

You can view, identify, query and edit features by taking specific features and feature layers offline with this API. Do this by exporting and downloading the features to geodatabase feature tables within a mobile geodatabase. The only limitations to this process are that the feature service must be from ArcGIS for Server 10.2.2 or later, or from a service hosted in ArcGIS Online. The feature service must have sync enabled capabilities (allow disconnected editing with synchronization).

You can use a existing feature service or create features services for your own data. To enable sync for a feature service:

  • In ArcGIS Online: you must edit the feature service item and check the Sync check box.
  • In ArcGIS Server: see the Prepare data for offline use in the ArcGIS Server documentation.

To create the mobile geodatabase you must:

  1. Generate the geodatabase parameters and define the area of interest, the layers, any expression filters etc., if required.
  2. Create the geodatabase, populated it with all the relevant features, and downloaded it to the user's device.

Generate geodatabase parameters

When you create a mobile geodatabase you must provide a set of parameters to define exactly which data is downloaded. You can specify the following:

  • The geographical area of interest. You typically supply the area of interest as an extent (envelope, in other words) but point, line, and polygon (including multipart) geometries are also supported. This allows you to create more detailed areas of interest. Regardless of the geometry, any features that intersect with the supplied area of interest are extracted.
  • The spatial reference of the mobile geodatabase.
  • Individual layers can be managed using the layerOptions property:
    • Determine which layers are included in the mobile geodatabase.
    • Subset the features by providing an expression that filters features by attribute values, such as ZONE = 'COM'.
    • The synchronization model controls how edits made to the mobile geodatabase are applied back to the feature service during synchronization. The model supported is defined by the data that was used to create the sync-enabled feature service. If the data is non-versioned, the synchronization model is per-layer. This is the most flexible model, allowing you to synchronize on a layer-by-layer basis, based on the layers you specify. If the data is versioned, the synchronization model is per-geodatabase. This synchronizes the entire geodatabase, including all layers and tables at once.
    • Specify whether to include feature attachments in the mobile geodatabase and whether they can be uploaded during synchronization.
    • Identify whether tables related to the layer are also included in the geodatabase.

You can obtain a default set of parameters (AGSGenerateGeodatabaseParameters) using the defaultGenerateGeodatabaseParameters method on the AGSGeodatabaseSyncTask. If you provide the area of interest the default parameters will be generated taking into account the capabilities supported by the ArcGIS feature service. You can update these default parameter values before creating the geodatabase.

//Instantiate the Geodatabase Sync Task
guard let url = URL(string: "http://sampleserver6.arcgisonline.com/arcgis/rest/services/Sync/SaveTheBaySync/FeatureServer") else {
 print("URL not accessible")
 return
}      
geodatabaseSyncTask = AGSGeodatabaseSyncTask(url: url)
//
// define an extent within which the features are included
let extent = self.mapView.currentViewpoint(with: .boundingGeometry)?.targetGeometry as! AGSEnvelope
//
// get the default parameters for generating a geodatabase
geodatabaseSyncTask?.defaultGenerateGeodatabaseParameters(withExtent: extent, completion: {[weak self] (parameters, error) in
 if let error = error {
  print(error)
  return
 }
 guard parameters != nil else {
  print("No parameters")
  return
 }
 if let parameters = parameters {
  //
  // set some of the parameters
  parameters.syncModel = .layer
  // define the layers and features to include
  let marineLayerId = 0
  let birdsLayerId = 1
  let dolphinsOnlyWhereClause = "type = 11"
  // clear and re-create the layer options
  parameters.layerOptions.removeAll()
  parameters.layerOptions.append(AGSGenerateLayerOption(layerID: marineLayerId, whereClause: dolphinsOnlyWhereClause))
  parameters.layerOptions.append(AGSGenerateLayerOption(layerID: birdsLayerId, includeRelated: true))
  // do not return attachments
  parameters.returnAttachments = false
  //
  //
  // create the generate geodatabase job, pass in the parameters and an output path for the local geodatabase
  //...
 }
})

Create the geodatabase

Obtain a job to generate and download the geodatabase by passing the AGSGenerateGeodatabaseParameters to the generateJob method on the AGSGeodatabaseSyncTask. Run the job to generate and download the geodatabase to the device.

//Instantiate the Geodatabase Sync Task
//Get and set the parameters (as above)
//
// create the generate geodatabase job, pass in the parameters and an output path for the local geodatabase
let generateJob = self.geodatabaseSyncTask?.generateJob(with: parameters, downloadFileURL: downloadURL)
generateJob?.start(statusHandler: { (status) in
 if status == .succeeded {
  print("Job succeeded")}
 else if status == .failed {
  print("Job failed")}
 else {
  print("Sync in progress")}
 }, completion: { (geodatabase, error) in
  if let error = error {
   print(error)
   return
  }
  //work with the geodatabase
  //...   
 }
)

Your geodatabase is now on the local machine or device.

If you generate the geodatabase using these methods it will automatically register the geodatabase with its original service. This allows the data in the geodatabase to be synchronized with the original service. If you want to load this geodatabase onto a number of devices and allow those users to synchronize changes with the original service you must register these individual geodatabases with the original service.

Note:

For details on synchronizing offline feature edits refer to Sync offline edits.

Tiled layers

Tiled layers typically provide geographical context to your maps as basemaps that display beneath your operational data. You can export and download tile caches directly to your device from any tiled data source that is export enabled. ESRI provides a number of raster and vector basemaps for you to export and download:

Download raster tiled data

You can take raster tiled data offline by exporting and downloading the tiled data as a tile package (*.tpk) using the AGSExportTileCacheTask class. This task requires that the tiled map service supports the creation of an offline tile cache; specifically, it must enable the exportTiles operation. This can be found at the bottom of the service's HTML page.

To create the raster tile cache you must:

  1. Generate the default export tile cache parameters and set any of properties.
  2. Export and download the raster tile cache using the methods on the AGSExportTileCacheTask.

Generate export tile cache parameters

Construct a default set of parameters (AGSExportTileCacheParameters) by passing an area of interest along with the min and max scale thresholds to the exportTileCacheParameters method on the AGSExportTileCacheTask.

This method will return a set of parameters for the area of interest and will calculate the levels of detail (LODs) required to support the min and max scale for the service's tiling scheme. You can, if you wish, adjust these LOD levels or remove some before you download the cache.

//instantiate the export task with the URL to the tiled service
self.exportTileCacheTask = AGSExportTileCacheTask(url: self.tiledLayer.url!)
//
//export the tile cache parameters from the tiled service
self.exportTileCacheTask.exportTileCacheParameters(withAreaOfInterest: self.frameToExtent(), 
 minScale: self.mapView.mapScale, 
 maxScale: self.tiledLayer.maxScale) 
 {[weak self] (params: AGSExportTileCacheParameters?, error: Error?) in
 if let error = error {
  print(error)
  return
 }
 guard let params = params else {return}
 // obtain the export tile cache parameters
 // set these parameters and provide them to the exportTileCacheJob 
 // to download the tile cache to the device
 self?.exportTileCacheParameters = params
}

Export and download the raster tile cache

Obtain an export and download job by passing the AGSExportTileCacheParameters to the exportTileCacheJob method on the AGSExportTileCacheTask. Run the job to download the raster tile cache into a tile package that is placed in the download path on the device.

//destination path for the tpk, including name
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let destinationPath = "\(path)/myTileCache.tpk"
//        
//get the job
self.exportTileCachejob = self.exportTileCacheTask.exportTileCacheJob(with: self.exportTileCacheParameters, downloadFileURL: URL(string: destinationPath)!)
//run the job
self.exportTileCachejob.start(statusHandler: { (status: AGSJobStatus) -> Void in
 //show job status
 print(status)})
 { [weak self] (result: AnyObject?, error: Error?) -> Void in
  if let error = error {
   print(error)
   return
  }
  //check the result is a TileCache then add it to the map
  guard let tileCache = result as? AGSTileCache else {return}
  let newTiledLayer = AGSArcGISTiledLayer(tileCache: tileCache)
  self?.map = AGSMap(basemap: AGSBasemap(baseLayer: newTiledLayer))
 }

When creating an offline tile cache from a tiled service, consider the following:

  • The export tiles operation used to generate tile caches is only available with services hosted on ArcGIS 10.2.1 for Server or later.
  • Estimation of tile cache size is not available on ArcGIS Online hosted tiled services.
  • The time required to create a tile cache varies depending on the extent requested, the number of levels requested, the network connection speed, and so on. Use the estimateTileCacheSizeJobWithParameters method on the AGSExportTileCacheTask class which returns an AGSEstimateTileCacheTaskJob to get the approximate size of a tile cache for a specific set of parameters. Try generating a smaller tile cache to get an idea of how long caching will take when planning a large offline data capture event.
  • There is a limit to the number of tiles you can generate in a single request. When generating a tile cache from an ArcGIS Online basemap, there is a limit of 100,000 tiles per request. Read more on this in the ArcGIS REST API Documentation. Organizations that use their own ArcGIS Server to host an offline tile cache can configure the server's maxExportTilesCount via the admin account to change the default limit of 100,000 tiles.

Download vector tiled data

You can take vector tiled data offline by exporting it from an ArcGIS Vector Tile Service and downloading it as a vector tile package (*.vtpk) using the AGSExportVectorTilesTask class. The vector tile service used for this operation must support the creation of an offline vector tile cache; specifically, it must enable the exportTiles operation. Vector tiles contain vector representations of data that can be restyled for different purposes such as day and night viewing. You can download default styling resources along with the vector tiles and custom style resources from ArcGIS Portal items that host Vector Tile Layers.

You have a number of workflows available to you depending on whether your vector tiled data has custom style resources, whether you wish to download a many custom styles that you can apply to a number of tile caches, or whether you just want to obtain the default tile cache.

Here are the steps required to create an vector tile package (*.vtpk) and vector tile style resources.

  1. Instantiate the export vector tiles task and check whether the vector tiles have custom style resources.
  2. Specify the export vector tile task parameters for a specific maximum scale and area of interest.
  3. Export the vector tiles with custom style resources. The vector tile package is populated with vector tiles from the ArcGIS Vector Tile Service along with the custom style resources specified by the ArcGIS Vector Tile Layer.
  4. Export custom style resources. These are the custom style resources specified by the ArcGIS Vector Tile Layer.
  5. Export the vector tiles with default style resources. The vector tile package is populated with vector tiles and the default style resources from the ArcGIS Vector Tile Service.

Instantiate the export vector tiles task

Instantiate the AGSExportVectorTilesTask using a URL to the portal item that represents an ArcGIS Vector Tiled Layer. Load the task and upon completion check whether the vector tiles have custom style resources by checking the hasStyleResources boolean value.

//initialize the export vector tiled task with a portal item that represents an ArcGIS Vector Tiled Layer
// or a URL to the ArcGIS Vector Tile service (if only default styles are required)
//
let portalItem = AGSPortalItem(portal: portal, itemID: itemID)        
self.exportVectorTilesTask = AGSExportVectorTilesTask(portalItem: portalItem)
//
self.exportVectorTilesTask.load {[weak self] (error) in
 if let error = error {
  print(error.localizedDescription)
  return
 }
 guard let hasStyleResources = self?.exportVectorTilesTask.hasStyleResources else {return}
 if hasStyleResources {
  print("The vector tile package has style resources")
  // choose whether to download the tiles and the custom style resources or just the style resources alone.
 }
}

Note:

You can instantiate the AGSExportVectorTilesTask with either

  • a URL to the portal item that represents an ArcGIS Vector Tiled Layer. This gives you the ability to enable with the layer's custom styles. (Recommended approach)
  • a URL to the ArcGIS Vector Tile Service itself. Use this option if you only want to display the service's default style.

Specify the export vector tiles task parameters

To obtain a default set of parameters call the defaultExportVectorTilesParametersWithAreaOfInterest:maxScale:completion: method and provide an area of interest and a maximum scale. When you provide the maximum scale you must be aware that there won't be any tiles when the map is zoomed in beyond this scale. If you set the max scale to 0 the export will include all levels of detail in the service.

This method returns the set of default parameters, AGSExportVectorTilesParameters, required to export the vector tiles to a vector tile package. The levels of detail (LODs) have been calculated to support the max scale that you specified.

self.exportVectorTilesTask.defaultExportVectorTilesParameters(withAreaOfInterest: self.frameToExtent(), maxScale: self.mapView.mapScale) {[weak self] (params: AGSExportVectorTilesParameters?, error: Error?) in
 if let error = error {
  print(error)
  return
 }
 // set the export vector tile cache parameters and set them where appropriate
 self?.exportVectorTilesParameters = params
}

Export the vector tiles with custom style resources

Obtain a job to generate and download a vector tile package containing tiles and associated style resources by passing the AGSExportVectorTilesParameters to the exportVectorTilesJob method on the AGSExportVectorTilesTask. The portal item's associated style resources will be downloaded and saved separately. You must also provide a download path to store the vector tile package and a separate download path for the style resources.

Run the job to export and download the vector tile package (*.vtpk) and the style resources to the device.

Note:

To obtain the vector tiles and its custom style resources you must instantiate the AGSExportVectorTilesTask with a portal item that represents an ArcGIS Vector Tiled Layer

guard let itemID = self.vectorTiledLayer.item?.itemID else {return}
let portalItem = AGSPortalItem(portal: portal, itemID: itemID)        
self.exportVectorTilesTask = AGSExportVectorTilesTask(portalItem: portalItem)
//        
//destination path for the vtpk, including name
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let VTPKPath = "\(path)/myVectorTileCache.vtpk"
let resourcesPath = "\(path)/styleResources"
//
//get the job
self.exportVectorTilesJob = self.exportVectorTilesTask.exportVectorTilesJob(with: self.exportVectorTilesParameters, 
 vectorTileCacheDownloadFileURL: URL(string: VTPKPath)!, 
 itemResourceCacheDownloadDirectory: URL(string: resourcesPath)!)
//
//run the job
self.exportVectorTilesJob.start(statusHandler: { (status: AGSJobStatus) -> Void in
//show job status
 print(status)})
 { [weak self] (result: AnyObject?, error: Error?) -> Void in
 if let error = error {
  print(error)
  return
 }
	//get the result
 guard let result = result as? AGSExportVectorTilesResult else {return}
 guard let vectorTileCache = result.vectorTileCache else {return}
 guard let itemResourceCache = result.itemResourceCache else {return}
 let newVectorTiledLayer = AGSArcGISVectorTiledLayer(vectorTileCache: vectorTileCache, itemResourceCache: itemResourceCache)
 self?.map = AGSMap(basemap: AGSBasemap(baseLayer: newVectorTiledLayer))
}

Export custom style resources

Obtain a job to download any custom style resources associated with the tasks vector tiles by passing a download path to the exportStyleResourceCacheJob method on the AGSExportVectorTilesTask.

Run the job to export the style resources. Obtain the AGSItemResourceCache from the AGSExportVectorTilesResult.

Note:

To obtain the custom style resources you must instantiate the AGSExportTileCacheTask with a portal item that represents an ArcGIS Vector Tiled Layer

//destination path for the style resources
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let resourcesPath = "\(path)/styleResources"
//
//get the job
self.exportVectorTilesJob = self.exportVectorTilesTask.exportStyleResourceCacheJob(withDownloadDirectory:URL(string: resourcesPath)!)
//
//run the job
self.exportVectorTilesJob.start(statusHandler: { (status: AGSJobStatus) -> Void in
 //show job status
 print(status)})
 { (result: AnyObject?, error: Error?) -> Void in
 if let error = error {
  print(error)
  return
 }
 guard let result = result as? AGSExportVectorTilesResult else {return}
 guard let itemResourceCache = result.itemResourceCache else {return}
 //....
}

Export the vector tiles with default style resources

Obtain a job to generate and download a vector tile package and it's default style resources by passing the AGSExportVectorTilesParameters to the exportVectorTilesJob method on the AGSExportVectorTilesTask. You must also provide a download path to store the vector tile package and it's default style resources.

Run the exportVectorTileCacheJob to export and download the vector tile package (*.vtpk).

Note:

To obtain the vector tiles and the default style resources you must instantiate the AGSExportTileCacheTask with a URL to the ArcGIS Vector Tile service.

//destination path for the tpk, including name
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let destinationPath = "\(path)/myVectorTileCache.vtpk"
//
//get the job
self.exportVectorTilesJob = self.exportVectorTilesTask.exportVectorTilesJob(with: self.exportVectorTilesParameters, downloadFileURL: URL(string: destinationPath)!)
//
//run the job
self.exportVectorTilesJob.start(statusHandler: { (status: AGSJobStatus) -> Void in
 //show job status
 print(status)})
 { [weak self] (result: AnyObject?, error: Error?) -> Void in
 if let error = error {
  print(error)
  return
 }
 //check the result is a vector tile cache then add it to the map
 guard let result = result as? AGSExportVectorTilesResult else {return}
 guard let vectorTileCache = result.vectorTileCache else {return}
 let newVectorTiledLayer = AGSArcGISVectorTiledLayer(vectorTileCache: vectorTileCache)
 self?.map = AGSMap(basemap: AGSBasemap(baseLayer: newVectorTiledLayer))
}

Desktop pattern

You can use ArcGIS Pro or ArcGIS Desktop to generate operational layers, basemaps, scene layers, locators and networks for use in ArcGIS Runtime. This workflow requires that you take this content, build your own maps and instantiate your own tasks to work with the locators and networks. If you'd like a ready-to-use and regularly updated locator (and network dataset) for your area of interest, you can license StreetMap Premium data (in MMPK format). For details, see Add StreetMap Premium data.

Create a mobile geodatabase for operational layers from ArcMap

To generate a geodatabase use the Share as > ArcGIS Runtime Content menu item as described in the ArcGIS help topic Creating ArcGIS Runtime content. This is available with ArcGIS 10.2.1 for Desktop or later.

Create a raster tile basemap

You can use ArcGIS Pro or ArcMap to create a raster tile basemap. For more details on how to set the format, tiling schemes, and levels of detail see:

After you sideload the tile package onto your device's file system, you can add it as a map's basemap.

Create a vector tile basemap

ArcGIS Pro allows you to author a map for vector tile creation and  create a vector tile package using a geoprocessing tool. You can add this local vector tile package (.vtpk) as a vector tiled layer (AGSArcGISVectorTiledLayer) to your ArcGIS Runtime app and create a basemap from it.