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', '~> 0.40'
    
  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" ~> 0.40
    
  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
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")

let options = NavigationRouteOptions(waypoints: [origin, destination])

Directions.shared.calculate(options) { (waypoints, routes, error) in
    guard let route = routes?.first else { return }

    let viewController = NavigationViewController(for: route)
    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 0.40.0

Packaging

  • This SDK can no longer be used in applications written in pure Objective-C. If you need to use this SDK’s public API from Objective-C code, you will need to implement a wrapper in Swift that bridges the subset of the API you need from Swift to Objective-C. (#2230)
  • Added a new dependency on MapboxAccounts to prepare for upcoming improvements to how Mapbox bills this SDK’s usage of Mapbox APIs. If you use Carthage to install this SDK, remember to add MapboxAccounts.framework to the “Frameworks, Libraries, and Embedded Content” section and the input and output file lists of Carthage’s Run Script build phase. (#2151)
  • Upgraded to Mapbox Maps SDK for iOS v5.6.x. (#2302)
  • Fixed sporadic build failures after installing this SDK using CocoaPods. (#2368)

Top and bottom banners

  • Removed BottomBannerViewController(delegate:) in favor of BottomBannerViewController() and the BottomBannerViewController.delegate property’s setter. (#2297)
  • Removed the StatusView.canChangeValue property in favor of StatusView.isEnabled. (#2297)

Map

Spoken instructions

User location

  • Removed the NavigationViewController.routeController property and LegacyRouteController(along:directions:dataSource:eventsManager:). To use LegacyRouteController instead of the default RouteController class, pass that type into MapboxNavigationService(route:directions:locationSource:eventsManagerType:simulating:routerType:), pass the MapboxNavigationService object into NavigationOptions(styles:navigationService:voiceController:topBanner:bottomBanner:), and pass the NavigationOptions object into NavigationViewController(route:navigationService:). To access LegacyRouteController, use the NavigationViewController.navigationService and NavigationService.router properties and cast the value of NavigationService.router to a LegacyRouteController. (#2297)
  • Removed the NavigationViewController.locationManager and LegacyRouteController.locationManager properties in favor of NavigationService.locationManager. (#2297)
  • Removed RouteLegProgress.upComingStep in favor of RouteLegProgress.upcomingStep. (#2297)
  • Removed the RouteProgress.nearbyCoordinates property in favor of RouteProgress.nearbyShape. (#2275, #2275)
  • Removed the LegacyRouteController.tunnelIntersectionManager property. (#2297)

Other changes

  • Various delegate protocols now provide default no-op implementations for all their methods and conform to the UnimplementedLogging protocol, which can inform you at runtime when a delegate method is called but has not been implemented. This replaces the use of optional methods, which are disallowed in pure Swift protocols. Messages are sent through Apple Unified Logging and can be disabled globally through Unifed Logging, or by overriding the delegate function with a no-op implementation. (#2230)
  • Removed NavigationViewController(for:styles:navigationService:voiceController:) and NavigationViewController(for:directions:styles:routeController:locationManager:voiceController:eventsManager:) in favor of NavigationViewController(route:options:). (#2297)
  • Removed the EventsManager type alias in favor of the NavigationEventsManager class. (#2297)
  • Removed the NavigationViewController.eventsManager and LegacyRouteController.eventsManager properties in favor of NavigationService.eventsManager. (#2297)
  • Removed the NavigationViewController.carPlayManager(_:didBeginNavigationWith:window:delegate:) and NavigationViewController.carPlayManagerDidEndNavigation(_:window:) methods. To mirror CarPlay navigation on the main device, present and dismiss a NavigationViewController in the CarPlayManagerDelegate.carPlayManager(_:didBeginNavigationWith:) and CarPlayManagerDelegate.carPlayManagerDidEndNavigation(_:) methods, respectively. (#2297)
  • When Dark Mode is enabled, user notifications now draw maneuver icons in white instead of black for better contrast. (#2283)
  • Added the RouteLegProgress.currentSpeedLimit property. (#2114)
  • Added convenience initializers for converting Turf geometry structures into MGLShape and MGLFeature objects such as MGLPolyline and MGLPolygonFeature. (#2308)
  • Fixed an issue where the “End Navigation” button in the end-of-route feedback panel appeared in English regardless of the current localization. (#2315)