Offline map setup

VERSION 0.40.0
PUBLIC PREVIEW

Offline functionality for the Maps and Navigation SDKs for iOS is only available upon request. Contact us to get started.

This guide expands upon the basic map configuration setup explained in the Offline map quickstart. It provides additional use cases and more detailed explanations of the configurations.

This guide shows you how to set up the geopolitical view, configure automatic map updates, and monitor offline map events. The code snippets in this guide reuse the examples from the Offline map quickstart.

Configuring geopolitical view

Boundary disputes and unsettled land claims exist between nations. These issues can lead to government prohibition of maps and devices that deviate from the local interpretation of the situation.

The parameter NDSStore.geopoliticalView can be provided to specify which view on disputed areas should be used:

1let ndsStore = try NDSStore(configuration: NDSStoreConfiguration(
2 mapDataPath: "path/to/map_directory/",
3 keystorePath: "path/to/keystore",
4 accessPermit: .mapLicense("your map license"),
5 geopoliticalView: "NLD" // Netherlands's view
6))

The international geopolitical view is used if no national view is provided or if no geopolitical view is defined in the map for the given nation.

Configuring offline map updates

To keep the offline maps up-to-date, TomTom supports over the air (OTA) updates. OTA updates use an internet connection. Since this connection can be metered and thus potentially cost the end-user money, keeping offline maps fresh must be managed. Our SDK provides two options to manage the updates to the offline maps. These options can work in parallel:

  • Automatic updates
  • Manual updates

The SDK provides the tools you need to configure and adjust the trade-offs to your specific use cases.

Through the NDSStoreUpdateConfig, you can configure the update parameters.

By default, the SDK uses the TomTom production update server. However, this setting can be configured to use any update server. If the server requires an API key, this must be provided in the configuration.

1let updateConfigWithCustomizedServer = NDSStoreUpdateConfig(
2 updateStoragePath: "path/to/directory/to/download/updates/",
3 persistentStoragePath: "path/to/directory/for/persistence/",
4 updateServerURL: URL(string: "https://YOUR_SERVER_URL"),
5 updateServerAPIKey: "YOUR_SERVER_API_KEY"
6)

Configuring automatic map updates

Automatic map updates leverage the user’s location and planned route to automatically control which map regions are kept up-to-date. The map regions that are more likely to be traversed by a user in a driving session are often referred to as relevant map regions. The relevant map regions are added if not already included in the offline map. The regions are updated with the latest available data if they are present. The SDK identifies the relevant regions and checks if new data is available for them. Any automatic updates are executed in the background.

Through NDSStoreUpdateConfig.AutomaticUpdatesConfiguration you can configure the automatic update parameters.

The relevant map regions can be selected as follows:

  • Relevant map regions around the current location - map regions that are within a specified radius around the current location.

regions around location

To enable the relevant map region updates based on the current location, simply set the NDSStoreUpdateConfig.AutomaticUpdatesConfiguration.relevantRegionsEnabled parameter to true. You can also customize the radius of the relevant regions and the update interval. For instance, if you want to check for map updates every hour within a 10-kilometer radius of the current location, you can configure this as shown in the following example:

1let updateConfigWithRelevantUpdates = NDSStoreUpdateConfig(
2 updateStoragePath: "path/to/directory/to/download/updates/",
3 persistentStoragePath: "path/to/directory/for/persistence/",
4 automaticUpdatesConfiguration: NDSStoreUpdateConfig.AutomaticUpdatesConfiguration(
5 relevantRegionsEnabled: true,
6 relevantRegionsRadius: Measurement.tt.kilometers(10),
7 relevantRegionsUpdateInterval: Measurement.tt.minutes(60)
8 )
9)
  • Relevant map regions along the route - map regions that intersect with the active route or are within a certain distance from the route and final destination.

regions along route

To configure the relevant map regions along the route, set NDSStoreUpdateConfig.AutomaticUpdatesConfiguration.regionsAlongRouteEnabled to true. Additionally, you can specify the radius around the route to your preferred value, e.g., 5 km:

1let updateConfigWithAlongRouteUpdates = NDSStoreUpdateConfig(
2 updateStoragePath: "path/to/directory/to/download/updates/",
3 persistentStoragePath: "path/to/directory/for/persistence/",
4 automaticUpdatesConfiguration: NDSStoreUpdateConfig.AutomaticUpdatesConfiguration(
5 regionsAlongRouteEnabled: true,
6 regionsAlongRouteRadius: Measurement.tt.kilometers(5)
7 )
8)

The relevant map regions are updated with no restrictions on connectivity type - meaning that they will also download data on metered network connections (such as mobile data).

NOTE: Configuring a larger radius results in more map regions being considered for updates. Updating more regions consequently results in an increase in network data consumption and an increase in the disk space usage by the offline map. This configuration must be tuned based on the needs of the end users.

  • In addition to the relevant map regions options, automatic map updates can also be configured to keep all map regions up-to-date.

That can be enabled as part of the configuration:

1let updateConfigWithAllRegionsEnabled = NDSStoreUpdateConfig(
2 updateStoragePath: "path/to/directory/to/download/updates/",
3 persistentStoragePath: "path/to/directory/for/persistence/",
4 automaticUpdatesConfiguration: NDSStoreUpdateConfig.AutomaticUpdatesConfiguration(
5 allRegionsEnabled: true
6 )
7)

In this case, all the map regions in the offline map are considered for updates in no particular order. This type of automatic map update is restricted to running only on unmetered network connections (such as wireless networks).

NOTE: Because all regions that are available for the offline map will be installed and updated, this configuration will significantly impact the data consumption and the disk size of the offline map.

Updating current position and active route

To ensure that the NDSStoreUpdater can identify the relevant map regions, you must update the current position or the active route to the NDSStoreUpdater.

  • For relevant region updates around the current position, use the NDSStoreUpdater.updatePosition(_:) API to update the current position.
  • For relevant region updates along the route, use the NDSStoreUpdater.updateActiveRoute(_:) API to update the active route.

You can get or subscribe to the current location via the LocationProvider. To set up the LocationProvider, see the Location Provider Quickstart.

1class MyLocationObserver: LocationProviderObservable {
2 // MARK: Lifecycle
3
4 public init(ndsStoreUpdater: NDSStoreUpdater) {
5 self.ndsStoreUpdater = ndsStoreUpdater
6 }
7
8 // MARK: Internal
9
10 func onLocationUpdated(location: TomTomSDKLocationProvider.GeoLocation) {
11 ndsStoreUpdater.updatePosition(location.location.coordinate)
12 }
13
14 func onHeadingUpdate(newHeading: CLHeading, lastLocation: TomTomSDKLocationProvider.GeoLocation) {}
15 func onAuthorizationStatusChanged(isGranted: Bool) {}
16
17 // MARK: Private
18
19 private let ndsStoreUpdater: NDSStoreUpdater
20}
locationProvider.addObserver(MyLocationObserver(ndsStoreUpdater: ndsStoreUpdater))

Notifications of offline map events

For automatic map update failures, you can add the AutomaticMapUpdateFailureObserver:

1class MyAutomaticUpdateFailureObserver: AutomaticMapUpdateFailureObserver {
2 func onAutomaticUpdateFailed(error: TomTomSDKNDSStoreUpdater.MapUpdateError) {
3 // Error handling - Your code goes here
4 // For example, print the error.
5 print(error.description)
6 }
7}
ndsStoreUpdater.addAutomaticMapUpdateFailureObserver(MyAutomaticUpdateFailureObserver())

You can also monitor the structure (see more in Manual map management) of the map and the current state of each map region via the RegionGraphObserver:

1class MyRegionGraphObserver: RegionGraphObserver {
2 func onRegionGraphChanged(event: TomTomSDKNDSStoreUpdater.RegionGraphChangeEvent) {
3 switch event {
4 case let .error(errorData):
5 // Error handling - Your code goes here.
6 // For example, print the error.
7 print(errorData.error.description)
8 case let .structureChanged(structureData):
9 // Your code goes here.
10 // For example, save the graph and the corresponding states.
11 graph = structureData.graph
12 nodeStates = structureData.nodeStates
13 case let .nodesStateChanged(nodesStateData):
14 // Your code goes here.
15 // For example, update the node states.
16 nodeStates.merge(nodesStateData.nodeStates) { _, new in new }
17 }
18 }
19
20 private var graph: RegionGraph?
21 private var nodeStates: [RegionGraphNodeID: RegionGraphNodeState] = [:]
22}
let regionGraphObserver = MyRegionGraphObserver()
ndsStoreUpdater.addRegionGraphObserver(regionGraphObserver)

Enabling/disabling map updates

Use the NDSStoreUpdater.updatesEnabled API to enable/disable updates. When updates are disabled during ongoing map operations, the operations are interrupted.

ndsStoreUpdater.updatesEnabled = true

Next steps

Since you have learned about offline maps and how to set them up, here are recommendations for the next steps:

By diving deeper into these areas, you can unlock the full potential of offline maps in your application.