Bring your own route
Demonstrates how to navigate along a custom route from a third-party server.
/*This code example is part of the Mapbox Navigation SDK for iOS demo app,which you can build and run: https://github.com/mapbox/mapbox-navigation-ios-examplesTo learn more about each example in this app, including descriptions and linksto documentation, see our docs: https://docs.mapbox.com/ios/navigation/examples/custom-server*/ import Foundationimport UIKitimport MapboxMapsimport MapboxCoreNavigationimport MapboxNavigationimport MapboxDirections class CustomServerViewController: UIViewController { let routeOptions = NavigationRouteOptions(coordinates: [CLLocationCoordinate2DMake(37.77440680146262, -122.43539772352648),CLLocationCoordinate2DMake(37.76556957793795, -122.42409811526268)]) var navigationViewController: NavigationViewController? override func viewDidLoad() {super.viewDidLoad() let routeOptions = self.routeOptionsDirections.shared.calculate(routeOptions) { [weak self] (_, result) inswitch result {case .failure(let error):print(error.localizedDescription)case .success(let response):guard let strongSelf = self else {return} // For demonstration purposes, simulate locations if the Simulate Navigation option is on.let indexedRouteResponse = IndexedRouteResponse(routeResponse: response, routeIndex: 0)let navigationService = MapboxNavigationService(indexedRouteResponse: indexedRouteResponse,customRoutingProvider: NavigationSettings.shared.directions,credentials: NavigationSettings.shared.directions.credentials,simulating: simulationIsEnabled ? .always : .onPoorGPS)let navigationOptions = NavigationOptions(navigationService: navigationService)strongSelf.navigationViewController = NavigationViewController(for: indexedRouteResponse,navigationOptions: navigationOptions)strongSelf.navigationViewController?.modalPresentationStyle = .fullScreenstrongSelf.navigationViewController?.delegate = strongSelf strongSelf.present(strongSelf.navigationViewController!, animated: true, completion: nil)}}}} extension CustomServerViewController: NavigationViewControllerDelegate {// Never reroute internally. Instead,// 1. Fetch a route from your server// 2. Map Match the coordinates from your server// 3. Set the route on your serverfunc navigationViewController(_ navigationViewController: NavigationViewController, shouldRerouteFrom location: CLLocation) -> Bool { // Here, we are simulating a custom server.let routeOptions = NavigationRouteOptions(waypoints: [Waypoint(location: location), self.routeOptions.waypoints.last!])Directions.shared.calculate(routeOptions) { [weak self] (_, result) inswitch result {case .failure(let error):print(error.localizedDescription)case .success(let response):guard let routeShape = response.routes?.first?.shape else {return} //// ❗️IMPORTANT❗️// Use `Directions.calculateRoutes(matching:completionHandler:)` for navigating on a map matching response.//let matchOptions = NavigationMatchOptions(coordinates: routeShape.coordinates) // By default, each waypoint separates two legs, so the user stops at each waypoint.// We want the user to navigate from the first coordinate to the last coordinate without any stops in between.// You can specify more intermediate waypoints here if you’d like.for waypoint in matchOptions.waypoints.dropFirst().dropLast() {waypoint.separatesLegs = false} Directions.shared.calculateRoutes(matching: matchOptions) { [weak self] (_, result) inswitch result {case .failure(let error):print(error.localizedDescription)case .success(let response):guard !(response.routes?.isEmpty ?? true) else {return} // Convert matchOptions to `RouteOptions`let routeOptions = RouteOptions(matchOptions: matchOptions) // Set the routeself?.navigationViewController?.navigationService.router.updateRoute(with: .init(routeResponse: response, routeIndex: 0),routeOptions: routeOptions,completion: nil)}}}} return true} func navigationViewControllerDidDismiss(_ navigationViewController: NavigationViewController, byCanceling canceled: Bool) {dismiss(animated: true, completion: nil)}}