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.8.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.8.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.8' # Latest prerelease pod 'MapboxCoreNavigation', :git => 'https://github.com/mapbox/mapbox-navigation-ios.git', :tag => 'v2.8.0' pod 'MapboxNavigation', :git => 'https://github.com/mapbox/mapbox-navigation-ios.git', :tag => 'v2.8.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.8.0
Packaging
- MapboxNavigation now requires MapboxMaps v10.8.x. (#4144)
- MapboxCoreNavigation now requires MapboxNavigationNative v115.x. (#4144)
- MapboxCoreNavigation now requires MapboxDirections v2.7.x. (#4181)
Location tracking
- Added
customActivityType
toMapboxNavigationService
initialization to allow overriding default activity type for location updates during this navigation session. Changed default activity type fromautomotiveNavigation
tootherNavigation
for.automobile
and.automobileAvoidingTraffic
profiles. (#4068) - Added
NavigationSettings.navigatorPredictionInterval
to control how far ahead Navigator will predict user current position. (#4072) - Added the
RoadGraph.Edge.Metadata.isUrban
andRoadObject.isUrban
properties and accompanying convenience initializers to indicate whether the edge or road object is in an urban area. (#4085) - Fixed an issue where some incidents in Japan were associated with two disconnected road edges, causing the
RoadGraph.Path
inRoadObject.Location.openLRLine(path:shape:)
to have the wrongRoadGraph.Path.edgeIdentifiers
. (valhalla/valhalla#3667, #4085) - Fixed an issue where the user location couldn’t be determined on iOS 13 and older versions. (#4113)
Map
- Fixed an issue where the route line layer appears above point of interest labels. (#4062)
- Fixed an issue where the destination building failed to highlight if the user has gotten rerouted at any time during the trip. (#4085)
- Fixed an issue where the map would cut off a continuous alternative route to appear as if it began after the deviation point. (#4085)
- Fixed an issue where the callout annotating a continuous alternative route appeared far away from the route and contained an inaccurate travel time. (#4085)
- Fixed an issue where some roads were shown as restricted on the route line even if public access is allowed for “local traffic only”. (#4085)
- Fixed an issue where the
NavigationMapView.traversedRouteColor
property had no effect on the traversed part of the route line. (#4106)
Guidance instructions
- Fixed an issue where the top banner and current road name label represented Mexican state highways with generic shields. (#4085)
- Fixed an issue where the route would instruct the user to make a “U-turn” toward the passenger side wherever the user should actually make two successive turns toward the passenger side or take an exit ramp that curves 180°. (#4085)
JunctionView
now appears after passing some toll booths or electronic toll collection points in Japan. (#4085)- Improved the pronunciation of junction names in Japanese in Japan. (#4085)
- At a fork or exit on an expressway in Japan, spoken instructions now mention the junction name and side of the road but no longer mention the expressway name or number that the user would stay on. (#4085)
- Fixed confusing instructions to take the roundabout in the Russian localization. (#4085)
- Fixed the crashes occured in guidance instructions during offline navigation. (#4147)
Routing
- After a fork in the road, if the user takes a different road than expected, RouteController now recognizes the actual road the user took more quickly than before. (#4085)
- Fixed an issue where a route would U-turn outside the destination parking lot, avoiding a more direct parking lot entrance. (#4085)
- If
RouteOptions.departAt
orRouteOptions.arriveBy
is set, the resulting route now respects turn restrictions that depend on the date or time. (#4085) - Eliminated the time penalty that was applied to barriers such as gates and border crossings, which was redundant to the effective time penalty from predicted speeds around the barrier. (#4085)
- A multi-leg route that crosses an international border can now have alternative routes. (#4085)
- Curvy roads are penalized slightly more consistently. (#4085)
- You can now set
Waypoint.allowsSnappingToStaticallyClosedRoad
totrue
to allow the waypoint to snap to a road that is fully closed for long-term construction. (#4085) - Added
NavigationSettings.liveIncidentsOptions
to configure how incidents data is fetched. (#4088) - Added
NavigationSettings.statusUpdatingSettings
to configure navigator status polling options. (#4135) - Added
RouterDelegate.router(_:modifiedOptionsForReroute:)
,NavigationServiceDelegate.navigationService(_:modifiedOptionsForReroute:)
andNavigationViewControllerDelegate.navigationViewController(_:modifiedOptionsForReroute:)
methods to allowRouteOptions
customization on reroutes. (#4102) - Fixed incorrect duration calculations and route refreshing when an arrival step’s geometry contained only one coordinate. Normally, an arrival step’s geometry is expected to be a zero-length
LineString
; that is, with two coincident coordinates. (#4110) - Routes now respect conditional access restrictions that depend on the year. (#4144)
- Routes now respect conditional access restrictions that apply to all vehicles. (#4144)
- Fixed an issue where the
Intersection.outletRoadClasses
andIntersection.outletMapboxStreetsRoadClass
properties were set toRoadClasses.restricted
for an entrance to a rest area because of its “local traffic only” restriction. (#4144) - Fixed an issue where continuous alternative time travel delta was displayed as 0 in a callout after manually switching to an alternative route. (#4177)
CarPlay
- Fixed an issue where navigation camera viewport padding was not taking into account
MapView
safe area insets on CarPlay. (#4098)
Other changes
- When launching the application, any stray files left over from old canceled offline tile downloads are cleaned up automatically to save storage space. (#4085)
- Fixed a “dereference error” when passing certain OpenLR identifiers into the
RoadObjectMatcher.matchOpenLR(location:identifier:)
method. (#4110) - Fixed an issue where the
RoadObjectMatcher.matchOpenLR(location:identifier:)
method sometimes returned the wrong parallel roadway. (#4110) - Removed the
Hashable
-conforming extension forCLLocationCoordinate2D
inMapboxCoreNavigation
to fix a compiler error in applications that define their ownHashable
conformance for this type. (#4109) - Fixed the crash that sometimes occurs when orientation of the view controller that contains
NavigationView
is being changed andNavigationView
’s parent view is being deallocated at the same time. (#4118)