Mapbox Navigation SDK for iOS
The Mapbox Navigation SDK gives you all the tools you need to add turn-by-turn navigation to your application. It takes just a few minutes to drop a full-fledged turn-by-turn navigation view controller into your application. Or use the Core Navigation framework directly to build something truly custom.
The Mapbox Navigation SDK and Core Navigation are compatible with applications written in Swift 5 in Xcode 10.2. The Mapbox Navigation and Mapbox Core Navigation frameworks run on iOS 10.0 and above.
Installation
Using Swift Package Manager
To install the MapboxNavigation framework in an application using Swift Package Manager:
Go to your Mapbox account dashboard and create an access token that has the
DOWNLOADS:READ
scope. PLEASE NOTE: This is not the same as your production Mapbox API token. Make sure to keep it private and do not insert it into any Info.plist file. Create a file named.netrc
in your home directory if it doesn’t already exist, then add the following lines to the end of the file:machine api.mapbox.com login mapbox password PRIVATE_MAPBOX_API_TOKEN
where PRIVATE_MAPBOX_API_TOKEN is your Mapbox API token with the
DOWNLOADS:READ
scope.In Xcode, go to File ‣ Swift Packages ‣ Add Package Dependency.
Enter
https://github.com/mapbox/mapbox-navigation-ios.git
as the package repository and click Next.Set Rules to Version, Up to Next Major, and enter
2.4.0
as the minimum version requirement. Click Next.
To install the MapboxCoreNavigation framework in another package rather than an application, run swift package init
to create a Package.swift, then add the following dependency:
// Latest prerelease
.package(name: "MapboxNavigation", url: "https://github.com/mapbox/mapbox-navigation-ios.git", from: "2.4.0")
Using CocoaPods
To install the MapboxNavigation framework using CocoaPods:
Go to your Mapbox account dashboard and create an access token that has the
DOWNLOADS:READ
scope. PLEASE NOTE: This is not the same as your production Mapbox API token. Make sure to keep it private and do not insert it into any Info.plist file. Create a file named.netrc
in your home directory if it doesn’t already exist, then add the following lines to the end of the file:machine api.mapbox.com login mapbox password PRIVATE_MAPBOX_API_TOKEN
where PRIVATE_MAPBOX_API_TOKEN is your Mapbox API token with the
DOWNLOADS:READ
scope.Create a Podfile with the following specification:
# Latest stable release pod 'MapboxNavigation', '~> 2.4' # Latest prerelease pod 'MapboxCoreNavigation', :git => 'https://github.com/mapbox/mapbox-navigation-ios.git', :tag => 'v2.4.0' pod 'MapboxNavigation', :git => 'https://github.com/mapbox/mapbox-navigation-ios.git', :tag => 'v2.4.0'
Run
pod repo update && pod install
and open the resulting Xcode workspace.
Configuration
Mapbox APIs and vector tiles require a Mapbox account and API access token. In the project editor, select the application target, then go to the Info tab. Under the “Custom iOS Target Properties” section, set
MBXAccessToken
to your access token. You can obtain an access token from the Mapbox account page. Usage of Mapbox APIs is billed together based on monthly active users (MAU) rather than individually by HTTP request.In order for the SDK to track the user’s location as they move along the route, set
NSLocationWhenInUseUsageDescription
to:Shows your location on the map and helps improve the map.
Users expect the SDK to continue to track the user’s location and deliver audible instructions even while a different application is visible or the device is locked. Go to the Signing & Capabilities tab. Under the Background Modes section, enable “Audio, AirPlay, and Picture in Picture” and “Location updates”. (Alternatively, add the
audio
andlocation
values to theUIBackgroundModes
array in the Info tab.)
Now import the relevant modules and present a new NavigationViewController
. You can also push to a navigation view controller from within a storyboard if your application’s UI is laid out in Interface Builder.
import MapboxDirections
import MapboxCoreNavigation
import MapboxNavigation
// Define two waypoints to travel between
let origin = Waypoint(coordinate: CLLocationCoordinate2D(latitude: 38.9131752, longitude: -77.0324047), name: "Mapbox")
let destination = Waypoint(coordinate: CLLocationCoordinate2D(latitude: 38.8977, longitude: -77.0365), name: "White House")
// Set options
let routeOptions = NavigationRouteOptions(waypoints: [origin, destination])
// Request a route using MapboxDirections
Directions.shared.calculate(routeOptions) { [weak self] (session, result) in
switch result {
case .failure(let error):
print(error.localizedDescription)
case .success(let response):
guard let strongSelf = self else {
return
}
// Pass the generated route response to the the NavigationViewController
let viewController = NavigationViewController(for: response, routeIndex: 0, routeOptions: routeOptions)
viewController.modalPresentationStyle = .fullScreen
strongSelf.present(viewController, animated: true, completion: nil)
}
}
Starting points
This SDK is divided into two frameworks: the Mapbox Navigation framework (MapboxNavigation
) is the ready-made turn-by-turn navigation UI, while the Mapbox Core Navigation framework (MapboxCoreNavigation
) is responsible for the underlying navigation logic.
Mapbox Navigation
NavigationViewController
is the main class that encapsulates the entirety of the turn-by-turn navigation UI, orchestrating the map view, various UI elements, and the route controller. Your application would most likely present an instance of this class. The NavigationViewControllerDelegate
protocol allows your application to customize various aspects of the UI and react to location-related events as they occur.
NavigationMapView
is the map view at the center of the turn-by-turn navigation UI. You can also use this class independently of NavigationViewController
, for example to display a route preview map. The NavigationMapViewDelegate
protocol allows your application to customize various aspects of the map view’s appearance. PassiveLocationProvider
is an optional alternative to CLLocationManager
for use with any standalone MapView
or NavigationMapView
.
CarPlayManager
is the class that manages the CarPlay screen if your application is CarPlay-enabled. It provides a main map for browsing, a search interface that can be powered by the Mapbox Search SDK for iOS or MapboxGeocoder.swift, and a turn-by-turn navigation UI similar to the one provided by NavigationViewController
. Your UIApplicationDelegate
subclass can conform to the CarPlayManagerDelegate
protocol to manage handoffs between NavigationViewController
and the CarPlay device, as well as to customize some aspects of the CarPlay navigation experience. To take advantage of CarPlay functionality, your application must have a CarPlay navigation application entitlement and be built in Xcode 10 or above, and the user’s iPhone or iPad must have iOS 12 or above installed.
Core Navigation
MapboxNavigationService
is responsible for receiving user location updates and determining their relation to the route line. If you build a completely custom navigation UI, this is the class your code would interact with directly. The NavigationServiceDelegate
protocol allows your application to react to location-related events as they occur. Corresponding Notification
s from the NavigationService
‘s RouteController
are also posted to the shared NotificationCenter
. These notifications indicate the current state of the application in the form of a RouteProgress
object.
For further details, consult the guides and examples included with this API reference. If you have any questions, please see our help page. We welcome your bug reports, feature requests, and contributions.
Changes in version 2.4.0
Pricing
- ❗ Starting with version 2.4.0, we are implementing a grace period of 30-seconds for all navigation sessions started by Nav SDK. A session will be counted only after this time period has surpassed. This allows you to reduce the cost of using the SDK during development and testing of your applications, as well as in production. Grace period is especially helpful to decrease the cost of short Free Drive session that are just a transition between Active Guidance sessions, or when a session is aborted right after it was started.
Packaging
- MapboxNavigation now requires MapboxMaps v10.4.3. (#3832)
- MapboxCoreNavigation now requires MapboxNavigationNative v94.x. (#3806)
- MapboxCoreNavigation now requires MapboxDirections v2.4.x. (#3829)
User interface
FeedbackViewController
now supports changing styles based onStyleManager
. (#3764)- Deprecated the optional
StyleManagerDelegate.styleManager(_:viewForApplying:)
method. All views appearance will be refreshed based onStyleManager
. (#3764) - Fixed an issue where the map’s floating buttons are misaligned with its attribution button and sometimes untappable after rotating the device during turn-by-turn navigation. (#3776)
- Fixed an issue where the top instruction banner couldn’t be swiped back to the current one. (#3785)
- Fixed an issue where the road name label shows wrong shield image when applying custom style under poor network connection. (#3792)
- Added the
SpeedLimitView.shouldShowUnknownSpeedLimit
property which defines the view behavior if theSpeedLimitView.speedLimit
property isnil
. Setting this property totrue
will cause the view to display"--"
as a speed limit instead of theSpeedLimitView
being invisible. (#3798)
Location tracking
- Added the
RoadObject.Kind.railroadCrossing
enumeration case to represent a railroad crossing along the route. (#3765) - Throttled requests to the Mapbox Directions API while the user moves around in a parking lot that has not been mapped in detail. (#3765)
- If the user backtracks from the beginning of one leg of the route to the end of the previous leg, the user is no longer considered to be off-route; instead,
RouteProgress.currentLegProgress
decrements and other properties follow suit. (#3765) - Fixed a crash starting turn-by-turn navigation on some routes that included bridges and restricted-access roads. (#3765)
- Fixed an issue where the route line appeared to begin away from the user’s current location after the route was refreshed. (#3781)
- Fixed a memory leak after ending a turn-by-turn navigation session. (#3782)
- Fixed an issue where
RouteControllerWillReroute
notification was incorrectly sent when a reroute was already in progress. (#3772) - Fixed an issue when
SimulatedLocationManager
could freeze the main thread when working with long routes. The manager now calls delegate methods from a background thread. (#3672) - Fixed an issue where initial puck position can be incorrect when
NavigationViewController
is presented. (#3773) - Fixed an issue where
UserHaloCourseView
was not correctly shown while changingCLLocationManager.accuracyAuthorization
andCLLocationManager.authorizationStatus
. (#3804)
Offline routing
- In bilingual and multilingual areas, spoken and visual instructions include street names and destinations in the user’s preferred language when that language is signposted. (#3765)
- Fixed
Intersection.outletIndex
values that were off by one. (#3765) - High-occupancy vehicle roads in OpenStreetMap that lack a
hov:minimum
tag are now assumed to be HOV 2+ roads, requiring one or more passengers. (#3765) - Decreased memory usage when starting turn-by-turn navigation along a long-distance route. (#3765)
- Fixed an issue where street names in spoken instructions could be go unpronounced if tagged with a pronunciation. (#3765)
- Added support for the workaround for requesting a route that avoids an arbitrary set of coordinates. (#3765)
CarPlay
- Fixed an issue where CarPlay application was crashing during template dismissal on iOS 14 and higher. (#3794)
- Added the ability to style each route line differently on CarPlay during route preview and active navigation using such delegate methods (#3744):
CarPlayManagerDelegate.carPlayManager(_:routeLineLayerWithIdentifier:sourceIdentifier:for:)
to style the route.CarPlayManagerDelegate.carPlayManager(_:routeCasingLineLayerWithIdentifier:sourceIdentifier:for:)
to style the casing of the route.
- Added
CarPlayManager.previewRoutes(for:)
to provide the ability to preview routes based on response from Mapbox Directions. (#3807)
Other changes
- Added the
MapboxSpeechSynthesizer(remoteSpeechSynthesizer:)
initializer for creating aMapboxSpeechSynthesizer
object that uses a customSpeechSynthesizer
instance. (#3747) - MapboxNavigationNative now sends messages to the Unified Logging subsystem
com.mapbox
for easier filtering. (#3765) HistoryRecording
static methods are deprecated in favor of instance methods. Using these instance variants onRouteController
orPassiveLocationManager
ensures correct history events recording and storing. (#3791)- Fixed a bug which caused
RouteOptions.profileIdentifier
to be ignored in active navigation. This may have caused elevated network usage. (#3796)