Mapbox Navigation SDK for iOS

Mapbox Navigation SDK

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:

  1. 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.

  2. In Xcode, go to File ‣ Swift Packages ‣ Add Package Dependency.

  3. Enter https://github.com/mapbox/mapbox-navigation-ios.git as the package repository and click Next.

  4. Set Rules to Version, Up to Next Major, and enter 2.0.0-rc.2 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.0.0-rc.2")

Using CocoaPods

To install the MapboxNavigation framework using CocoaPods:

  1. 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.

  2. Create a Podfile with the following specification:

    # Latest stable release
    pod 'MapboxNavigation', '~> 2.0'
    # Latest prerelease
    pod 'MapboxCoreNavigation', :git => 'https://github.com/mapbox/mapbox-navigation-ios.git', :tag => 'v2.0.0-rc.2'
    pod 'MapboxNavigation', :git => 'https://github.com/mapbox/mapbox-navigation-ios.git', :tag => 'v2.0.0-rc.2'
    
  3. Run pod repo update && pod install and open the resulting Xcode workspace.

Configuration

  1. 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.

  2. 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.

  3. 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 and location values to the UIBackgroundModes 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 Notifications 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.0.0

Packaging

  • Choose from two new pricing options depending on your use case: per-trip or unlimited trips. (#3147, #3338)
  • The Mapbox Navigation SDK for iOS license has changed from the ISC License to the Mapbox Terms of Service. (#2808)
  • To gain access to Mapbox server APIs, set MBXAccessToken in your Info.plist. MGLMapboxAccessToken is deprecated and no longer supported by NavigationMapView. (#2837)
  • The MBXNavigationBillingMethod Info.plist key is no longer supported. (#3147)

System requirements

  • MapboxNavigation and MapboxCoreNavigation require iOS 11.0 or above to run. iOS 10.x is no longer supported. (#2808)
  • Xcode 12.4 or above is now required for building this SDK from source.
  • You can build MapboxNavigation for an iOS simulator on an Apple Silicon–powered Mac. (#3031)
  • You can now install MapboxNavigation using Swift Package Manager, but you can no longer install it using Carthage. If you previously installed MapboxNavigation using Carthage, use Swift Package Manager instead. (#2808)
  • Carthage v0.38 or above is now required for installing this SDK if you use Carthage. (#3031)
  • Added a Castilian Spanish localization. (#3186)

Dependencies

Map

Camera

User location indicator

Route overlay

  • Removed the NavigationAnnotation class. (#2808)
  • Renamed the MBRouteLineWidthByZoomLevel property to Constants.RouteLineWidthByZoomLevel and changed its type to Double for keys and values. (#2808)
  • Renamed the MBCurrentLegAttribute and MBCongestionAttribute constants to Constants.CurrentLegAttribute and Constants.CongestionAttribute, respectively. (#2808)
  • Added the NavigationMapView.navigationMapView(_:didAdd:pointAnnotationManager:) and NavigationViewController.navigationViewController(_:didAdd:pointAnnotationManager:) delegate methods, which are called whenever a PointAnnotation is added to a NavigationMapView or NavigationViewController, respectively, to represent the final destination. Added the NavigationMapView.pointAnnotationManager property for managing point annotations. (#2961, #3109)
  • When specifying the legIndex in NavigationMapView.show(_:legIndex:), the route line for the specific route leg shows color-coded congestion segments, while other route legs are stroked with NavigationMapView.routeCasingColor by default. If the leg index is unspecified, all the route legs show color-coded congestion. During turn-by-turn navigation, the default specified route leg is the current route leg. You can override the route leg colors using properties such as NavigationMapView.routeCasingColor and NavigationMapView.trafficHeavyColor. Added the NavigationMapView.showsCongestionForAlternativeRoutes property to show congestion levels with different colors on alternative route lines. (#2833, #2887)
  • Fixed an issue where the route line disappears when changing a NavigationMapView’s style. (#3136)
  • Renamed the NavigationMapView.updateRoute(_:) method to NavigationMapView.travelAlongRouteLine(to:). Improved the performance of updating the route line to change color at the user’s location as they progress along the route. (#3201).
  • Fixed an issue where the route line grows backwards when the NavigationViewController.routeLineTracksTraversal property is set to true and the user passes the destination. (#3255)
  • Fixed incorrect color-coded traffic congestion along the route line and incorrect speeds in the speed limit view after some time had elapsed after rerouting. (#3344)
  • By default, there is no longer a subtle crossfade between traffic congestion segments along a route line. To reenable this crossfade, set the NavigationMapView.crossfadesCongestionSegments property to true. You can also adjust the length of this crossfade using the global variable GradientCongestionFadingDistance. (#3153, #3307)
  • The duration annotations added by the NavigationMapView.showRouteDurations(along:) method are now set in the fonts you specify using the NavigationMapView.routeDurationAnnotationFontNames property. Use this property to specify a list of fallback fonts for better language support. (#2873)
  • Fixed an issue when route line was sometimes invisible after starting turn-by-turn navigation. (#3205)

Banners and guidance instructions

  • Removed the InstructionsBannerViewDelegate.didDragInstructionsBanner(_:) method. (#2808)
  • Removed the StatusView.delegate and StatusView.canChangeValue properties and the StatusViewDelegate and DeprecatedStatusViewDelegate protocols. (#2993)
  • Removed the BottomBannerViewController(delegate:) initializer. (#2993)
  • The top banner can now show a wider variety of turn lane configurations, such as combination U-turn/left turn lanes and combination through/slight right turn lanes. (#2882)
  • Fixed an issue where the current road name label flashed when the camera state changed or the user traveled onto an unnamed road. (#2958)
  • Fixed an issue where the current road name label sometimes displayed the name of an intersecting road instead of the current road or blinked in and out. (#3257)
  • Fixed an issue where lane guidance icons would sometimes highlight the wrong arrow. (#2942)
  • Fixed an issue where instruction banners could appear in the wrong color after switching between Styles. (#2977)
  • Fixed an issue where GenericRouteShield images would ignore changing its foreground color in favor of a cached image. (#3217)
  • Fixed an issue where some banner instructions were occasionally skipped. (#3265)
  • Improved the current road name label’s performance and fixed a potential crash when updating it. (#3340)

Location tracking

Passive navigation

Rerouting

Predictive caching and offline navigation

Electronic horizon and route alerts

CarPlay

User feedback

Other changes