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 CocoaPods

To install Mapbox Navigation using CocoaPods:

  1. Create a Podfile with the following specification:

    pod 'MapboxNavigation', '~> 1.0'
    
  2. Run pod repo update && pod install and open the resulting Xcode workspace.

Using Carthage

Alternatively, to install Mapbox Navigation using Carthage:

  1. Create a Cartfile with the following dependency:

    github "mapbox/mapbox-navigation-ios" ~> 1.0
    
  2. Run carthage update --platform iOS to build just the iOS dependencies.

  3. Follow the rest of Carthage’s iOS integration instructions. Your application target’s Embedded Frameworks should include MapboxNavigation.framework, MapboxCoreNavigation.framework, and MapboxNavigationNative.framework.

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 MGLMapboxAccessToken to your access token. You can obtain an access token from the Mapbox account page.

  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 route = response.routes?.first, let strongSelf = self else {
            return
        }
        // Pass the generated route to the the NavigationViewController
        let viewController = NavigationViewController(for: route, 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.

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 powered by 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 1.0.0

Packaging

  • Carthage v0.35 or above is now required for installing this SDK if you use Carthage. (81a36d0)
  • For the time being, MapboxCoreNavigation.framework depends on a build of MapboxNavigationNative.framework that is only available to authorized beta testers. Please contact your Mapbox sales representative or support team to learn more about the beta testing program. (#2412)
  • Xcode 11.4.1 or above is now required for building this SDK from source. (#2417)
  • Enabled MAU billing by default, so that SDKs usage of Mapbox APIs is billed together based on monthly active users rather than individually by HTTP request. If you prefer to still use request-based billing, set the MBXNavigationBillingMethod key in Info.plist to request (#2405.
  • Added a Greek localization. (#2385)

User location

  • Fixed an issue where various delegate methods omitted CLLocation.courseAccuracy and CLLocation.speedAccuracy properties from passed-in CLLocation objects when using RouteController, even when these properties are provided by Core Location on iOS 13.4 and above. (#2417)
  • Fixed issues where the user puck would sometimes drift away from the route line even though the user was following the route. (#2412, #2417)
  • Fixed an issue where RouteController took longer than usual to detect that the user had gone off-route. (#2412)
  • Fixed an issue where RouteController would detect that the user had gone off-route due to a single errant location update. (#2412, #2417)
  • Fixed an issue where the camera and user puck would cut a corner when making a turn at speed. (#2412)
  • Fixed an issue where RouteController became too sensitive to the user going off-route near “intersections” that the Mapbox Directions API synthesizes at road classification changes, such as at either end of a tunnel. (#2412)
  • If the user’s raw course as reported by Core Location differs significantly from the direction of the road ahead, the camera and user puck are oriented according to the raw course. (#2417)
  • RouteController now tracks the user’s location more accurately within roundabouts. (#2417)
  • Fixed an issue where departure instructions were briefly missing when beginning turn-by-turn navigation. (#2417)

User location

  • Improved the accuracy of location tracking and off-route detection. (#2319)
  • Fixed an issue where location tracking would pause at the beginning of a route after setting RouteOptions.shapeFormat to RouteShapeFormat.polyline or RouteShapeFormat.geoJSON. Note that you most likely do not need to override the default value of RouteShapeFormat.polyline6: this is the least bandwidth-intensive format, and Route.shape and RouteStep.shape are set to LineStrings regardless. (#2319)

Offline navigation

  • Fixed a crash that occurred after setting RouteOptions.shapeFormat to RouteShapeFormat.geoJSON. (valhalla/valhalla#1867)
  • Fixed an issue where some routes had unreasonably long expected travel times. (valhalla/valhalla#2102)
  • Fixed incorrect routing at some intersections of divided roads where there are turn restrictions. (valhalla/valhalla#2109)
  • Fixed issues where routes would sometimes require divebombing. (valhalla/valhalla#1931)
  • Fixed an issue where the route would sometimes contain duplicate waypoints. (valhalla/valhalla#1880)
  • Fixed an issue where an exception to a road closure on a public holiday was being ignored. (valhalla/valhalla#2198)
  • By default, calculated routes follow alleys less often. (valhalla/valhalla#2231)
  • When RouteOptions.profileIdentifier is set to DirectionsProfileIdentifier.cycling, the calculated route may now follow paths tagged with mountain biking difficulty levels in OpenStreetMap. (valhalla/valhalla#2117)
  • Fixed an issue where floating-point numbers in tags were parsed incorrectly. (valhalla/valhalla#2355)
  • When two maneuvers are spaced close together, the spoken instruction now describes both maneuvers. (valhalla/valhalla#2353)
  • Turn lane indications are now shown below the turn banner as when navigating online. (valhalla/valhalla#1830, valhalla/valhalla#1859)
  • Fixed an issue where the RouteStep.expectedTravelTime properties of each step did not add up to the RouteLeg.expectedTravelTime property. (valhalla/valhalla#2195)
  • Fixed an issue where a forward- or backward-only speed limit was not considered when calculating some expected travel times. (valhalla/valhalla#2198)
  • Suppressed extraneous ManeuverType.reachFork maneuvers. (valhalla/valhalla#1886, valhalla/valhalla#1909, valhalla/valhalla#1928)
  • A spoken instruction about a ManeuverType.merge maneuver now indicates whether to merge to the left or the right, as when navigating online. (valhalla/valhalla#1892, valhalla/valhalla#1989)
  • Spoken instructions for ManeuverType.exitRoundabout and ManeuverType.exitRotary maneuvers now indicate the outlet road name or destination if available. (valhalla/valhalla#2378)
  • Fixed ungrammatical spoken instructions at sharp turns in English. (valhalla/valhalla#2226)
  • Fixed an issue where spoken and visual instructions sometimes omitted the cardinal direction after a route number in the United States. (valhalla/valhalla#1917)
  • A spoken instruction about a ManeuverType.takeOffRamp maneuver no longer specifies the side of the road if the ramp branches off the slow lane (on the right side in regions that drive on the right). (valhalla/valhalla#1990)
  • Improved the timing of spoken instructions for ManeuverType.takeOffRamp maneuvers along high-speed roads. (#2417)
  • Improved the timing of visual instructions when two maneuvers are spaced close together. (#2417)

Feedback

  • Updated FeedbackType enum to reflect new top level feedback categories and introduced new FeedbackSubTypes to support a more granular feedback mechanism. (#2419)
  • Updated image icons for top-level feedback collection view items. (#2419, #2421)
  • The feedback screen no longer dismisses automatically after 10 seconds. (#2420)

Other changes