Download Offline Maps package

Maps Package is the actual downloadable and installable map content for a region. This guide covers how to register the download progress listener, monitor progress and handle any errors.

Register the progress listener first

It is recommended to register progress listeners before enqueueing a download. Register the progress listener before starting a download:

1
private var progressToken: NGLRegionalOfflineListenerToken?
2
private var selectedRegionId: Int?
3
4
func observeDownloadProgress() {
5
progressToken = NGLRegionalOffline.addDownloadProgressListener {
6
[weak self] progressByRegionId in
7
guard let self, let regionId = selectedRegionId else { return }
8
9
let key = NSNumber(value: regionId)
10
guard let progress = progressByRegionId[key] else { return }
11
12
progressView.progress = Float(progress.percent) / 100.0
13
statusLabel.text = NGLRegionalOfflineDownloadStateLabel(progress.state)
14
15
switch progress.state {
16
case .completed:
17
statusLabel.text = "Download complete"
18
19
case .failed, .failedStorage:
20
handleRegionalOfflineError(progress.error)
21
22
default:
23
break
24
}
25
}
26
}

The initial listener snapshot is delivered on the main thread and may run before registration returns when called from the main thread. Subsequent callbacks are also delivered on the main thread.

Enqueue a download

1
func download(regionId: Int, replacingExistingData: Bool = false) {
2
NGLRegionalOffline.downloadRegion(
3
withId: regionId,
4
clearBefore: replacingExistingData
5
) { [weak self] error in
6
guard let self else { return }
7
8
if let error {
9
// Shared resource preparation, region detail, or enqueue failure.
10
handleRegionalOfflineError(error)
11
return
12
}
13
14
// nil means that the task was enqueued. It does not mean that the
15
// regional package has finished downloading.
16
}
17
}

Note that the enqueue completion only reports whether the task was accepted, it does not report the final download result. Use the progress listener to determine the final result.

Also, it is recommended to handle enqueue and transfer errors separately.

Understanding the two error paths

StageNotification pathExample failures
Before enqueueThe Error? passed to the downloadRegion completionInvalid region, region detail request failure, or duplicate active request
After enqueueNGLRegionalOfflineDownloadProgress.errorNetwork, HTTP, filesystem, insufficient storage, invalid package, decompression, installation, or Preview validation failure

Remove the progress listener

1
func removeDownloadProgressObserver() {
2
if let progressToken {
3
NGLRegionalOffline.removeDownloadProgressListener(progressToken)
4
self.progressToken = nil
5
}
6
}