Offline
This page uses v6.4.1 of the Mapbox Maps SDK. A newer version of the SDK is available. Learn about the latest version, v11.8.0, in the Maps SDK documentation.
The Maps SDK enables you to download and store preselected regions for when the device goes offline. The resulting map is fully functional and includes the styles, tiles, and other resources required to draw a complete map.
Limitations
An app can download multiple regions for offline use, but the total offline download is capped at a maximum tile count "ceiling" across all downloaded regions. The SDK sets the tile ceiling to 6,000 tiles per end user by default, but you can adjust this per-user limit. Six thousand tiles cover a region roughly the size of Greater London within the M25 motorway at zoom levels 0
–15
or the contiguous United States at zoom levels 0
–9
. The size of these tiles on disk will vary according to the selected style.
The Maps SDK places no limit on the number of offline regions that can be created, as long as the cumulative number of tiles used does not exceed the default or custom tile limit. Your Mapbox-powered application will reuse tiles and resources that are required by multiple regions, conserving network traffic and disk space. For information on how to increase your offline tile limit, see the Adjust the tile limit per user section of this guide. Note that you will be billed by Vector Tile API or Raster Tile API requests if either service's monthly free tier is exceeded. See the Offline maps pricing section for details.
Additionally, the SDK places no limit on the download speed of offline regions, nor to disk space used by offline resources. The limits will depend on the storage capacity of the mobile device and the speed of the network to which it is connected.
Our terms of service do not allow you or an end user to redistribute offline maps downloaded from Mapbox servers.
Pricing for offline maps
For information about how offline maps are priced for the Maps SDK, see our pricing guide.
Automatic tile updates
The Maps SDK downloads tiles when any connection is available, including over regular mobile data (2G, 3G, 4G, etc.). Because only individual highly-optimized tiles download, there is no risk of the user incurring an unexpected 100 MB download by opening the map in a region that's already downloaded. Unless the user is browsing 100 MB worth of tiles.
When the SDK automatically updates offline map tiles, such as when the cache expires, the offline region is not re-download from scratch. The offline tile update process is the same process as with regular map tiles: The map tile is only downloaded if there is a new version of that tile.
Downloading an offline map
Defining a region
Before a region can be used offline, the resources necessary for that region must be downloaded. Based on the parameters you specify when creating the region, the SDK calculates all resource requirements such as fonts, styles, and vector tiles covering the region. If more than one region in the offline database contains the fonts and styles, these will not be re-downloaded when another region with the same map style is downloaded. First, you'll need to define the pack to download by defining the region to save offline. You may also associate optional metadata with the pack if desired.
let region = MGLTilePyramidOfflineRegion(styleURL: mapView.styleURL, bounds: mapView.visibleCoordinateBounds, fromZoomLevel: mapView.zoomLevel, toZoomLevel: mapView.zoomLevel + 2)
// Store some data for identification purposes alongside the downloaded resources.
let userInfo = ["name": "\(region.bounds)"]
let context = NSKeyedArchiver.archivedData(withRootObject: userInfo)
Create offline pack
Next, you will need to register the region with the offline storage manager, and begin downloading the pack. You can also store any arbitrary metadata you would like to associate with the pack.
// Create and register an offline pack with the shared offline storage object.
MGLOfflineStorage.shared.addPack(for: region, withContext: context) { [self] (pack, error) in
guard error == nil else {
// The pack couldn’t be created for some reason.
print("Error: \(error?.localizedDescription ?? "unknown error")")
return
}
// Start downloading.
pack!.resume()
}
Besides creating the offline pack, you can also update the information stored, allowing your users, for example, to update the region name. The MGLOfflineStorage
object provides a method called addPack which takes in both the updated offline pack and a callback to be notified when the update is completed, or an error occurs.
Start download
To make this one seamless operation, we can place the definition of our region and context, as well as the addition of our offline pack to MGLOfflineStorage
, within one function startOfflinePackDownload
.
Now that the region has been created, you can call startOfflinePackDownload
to begin an asynchronous download.
extension UIViewController: MGLMapViewDelegate {
func mapViewDidFinishLoadingMap(_ mapView: MGLMapView) {
// put all the code here to create and download the pack instead of startOfflinePackDownload()
}
}
Managing downloaded regions
Once you or your user has downloaded a region, the Maps SDK provides a few options to handle gathering a list, positioning the camera inside the downloaded region, and a method for deleting a region.
List offline regions
The listing of regions is useful for presenting downloaded information to your user. For example, displaying all downloaded packs in a UITableView
could be useful to users who want to manage their downloaded offline maps. You may access these packs by way of the MGLOfflinePacks.shared.packs
property, as outlined in our manage offline regions example.
Delete a region
To remove an offline region from the database, call MGLOfflineStorage.shared.removePack:withCompletionHandler:
. Similarly to addPack
, this method can be called with optional completion handler that returns an error if the pack can't be removed.
Deleting a region will result in also removing the least recently requested resources not required by other regions until the database shrinks below a certain size.
guard let lastPack = MGLOfflineStorage.shared.packs?.last else { return }
MGLOfflineStorage.shared.removePack(lastPack) { (error) in
// Handle error if pack can't be removed.
if let error = error {
print(error)
} else {
// Perform some action upon successful pack removal.
}
}
Adjust the tile limit per user
For the Maps SDK for iOS v5.3.0 and higher there are no hard limits to the number of tiles your users can download. But because you are responsible for the cost of all tiles downloaded by your users, you may want to set an offline tile limit.
By default, the offline tile limit is set to 6,000. This means each of your users can download 6,000 tiles for offline use. To increase or decrease the number of offline tiles your users can download, you can set the offline tile limit by calling -[MGLOfflineStorage setMaximumAllowedMapboxTiles:]
.