Migrate from Mapbox

VERSION 0.2.1455
PUBLIC PREVIEW

This tutorial shows some of the differences between the Mapbox SDK and the TomTom SDKs. For this purpose, a simple navigation application was created using Mapbox and TomTom SDKs. The application displays a map with the user’s location on it. Next, the app draws a marker at a place that the user has selected with a long click on the map. It then calculates a route from the user’s location to the selected destination and adds it to the map. Finally, it performs navigation along the route.

This tutorial compares the TomTom SDK to the Mapbox Navigation SDK. Some implementations may vary from the Mapbox Maps SDK.

Project setup

The Navigation SDK for iOS is only available upon request. Contact us to get started.

  1. Install Xcode if you don’t already have it.
  2. Create a new project or open an existing one. The application deployment target has to be set to at least 13.0.
  3. Install Cocoapods on your computer.
  4. Install cocoapods-art tool on your computer.
  5. Because the repository for Navigation SDK is private, you will need to contact us to get access. Once you have obtained access, go to repositories.tomtom.com and log in with your account. Expand the user menu in the top-right corner, and select "Edit profile" → "Generate an Identity Token". Copy your token and put it, together with your login, in ~/.netrc. If the file doesn’t exist, create one and add the following entry:
    1machine repositories.tomtom.com
    2login <YOUR_LOGIN>
    3password <YOUR_TOKEN>
  6. Add a reference to the cocoapods-art repository:
    pod repo-art add tomtom-sdk-cocoapods "https://repositories.tomtom.com/artifactory/api/pods/cocoapods"
  7. Then create a Podfile in the project folder. The pod init command in the project folder can generate a basic podfile.
  8. At the top of the Podfile add the source of the SDK Cocoapods.
    1plugin 'cocoapods-art', :sources => [
    2 'tomtom-sdk-cocoapods'
    3]
  9. Add the modules that your project requires. This tutorial uses the TomTomSDKMapsDisplay, TomTomSDKOnlineRouting, and TomTomSDKNavigationEngine modules.
    1TOMTOM_SDK_VERSION = '{version}'
    2target 'YourAppTarget' do
    3 use_frameworks!
    4 pod 'TomTomSDKMapsDisplay', TOMTOM_SDK_VERSION
    5 pod 'TomTomSDKOnlineRouting', TOMTOM_SDK_VERSION
    6 pod 'TomTomSDKNavigationEngine', TOMTOM_SDK_VERSION
    7end
  10. Install the dependencies by executing the following command in the project folder.
    pod install
  11. To update the SDK version, run the command:
    pod repo-art update tomtom-sdk-cocoapods
  12. Create a class with the TomTom API keys. These will be used later in the application.
    1private enum Keys {
    2 static let MAPS_KEY = "YOUR_MAPS_API_KEY"
    3 static let ROUTING_KEY = "YOUR_ROUTING_API_KEY"
    4 static let NAVIGATION_KEY = "YOUR_NAVIGATION_API_KEY"
    5}

Displaying a map

Mapbox SDK

Before using the Mapbox SDK you need to set the public access token in the Info.plist.

  1. Initialize NavigationMapView. This draws a MapView and provides additional functionality such as drawing a route.
    navigationMapView = NavigationMapView(frame: view.bounds)
  2. Add the initialized TomTomMapView to the parent view.
    view.addSubview(navigationMapView)

TomTom SDKs

To do the same thing in the TomTom SDK for iOS:

  1. Set the valid TomTom API key.
    MapsDisplayService.mapsKey = Keys.MAPS_KEY
  2. Initialize the TomTomMapView. This is used to display a map in the view hierarchy.
    let mapView = TomTomMapView(frame: view.frame)
  3. Add the initialized TomTomMapView to the parent view.
    view.addSubview(mapView)
  4. Most actions performed on the map are made using the TomTomMap object. It can be accessed only when the map is fully initialized. Read more about it in the Adding a map guide.
    1mapView.getMapAsync { tomtomMap in
    2 self.tomTomMap = tomtomMap
    3}

center

Showing user location

To access the user location you have to configure the following purpose strings in the Xcode build setting or in Info.plist: NSLocationWhenInUseUsageDescription, NSLocationAlwaysAndWhenInUseUsageDescription, or NSLocationAlwaysUsageDescription. The correct key must be included or authorization requests will immediately fail and the map will not be able to get the user location.

Mapbox SDK

To show the user location on the map in the Mapbox SDK you have to set UserLocationStyle.

view.addSubview(navigationMapView)

To move the camera to the user location, set the ViewportDataSource.

1navigationMapView.navigationCamera.viewportDataSource = NavigationViewportDataSource(
2 navigationMapView.mapView,
3 viewportDataSourceType: .raw
4)

TomTom SDK

To show the user location on the map, change the TomTomMap.locationIndicatorType to either userLocation or .navigationChevron. By default, CLLocationManager is used as the source of location updates. However, you can also provide your own source. Read more about user location in the Showing the user’s location guide.

tomTomMap.locationIndicatorType = .userLocation

By default the center button is hidden, so to show it you need to change its visibility using TomTomMapView.

mapView.currentLocationButtonVisibilityPolicy = .hiddenWhenCentered

You can also set the camera to follow the user’s location. Do it using CameraTrackingMode.follow.

tomTomMap.cameraTrackingMode = .follow

center

Adding a marker

Mapbox SDK

  1. Adding a marker in the Mapbox SDK is made via PointAnnotationManager. Create it using MapView’s `AnnotationOrchestrator.
    let pointAnntotationManager = navigationMapView.mapView.annotations.makePointAnnotationManager()
  2. Initailize PointAnnotation to represent the marker. Use it to configure the appearance and properties of the marker.
    var pointAnnotation = PointAnnotation(coordinate: coordinate)
    pointAnnotation.image = .init(image: UIImage(named: "marker_pin")!, name: "destination")
  3. Set the created PointAnnotation to the collection managed by the PointAnnotationManager.
    pointAnntotationManager.annotations = [pointAnnotation]

TomTom SDK

To do the same in the TomTom SDK complete the following steps:

  1. Create the MarkerOptions object with the marker properties. You can use this object to configure the appearance of the marker.
    let markerOptions = MarkerOptions(coordinate: coordinate, pinImage: UIImage(named: "marker_pin_image")!)
  2. Set the created MarkerOptions to the TomTomMap object. Note that if adding a marker fails, an exception is thrown. Read more about working with markers in the TomTom SDK Adding a Marker document.
    _ = try? tomTomMap.addMarker(options: markerOptions)

Drawing a route

This section describes how to calculate and draw a route from the user location to the chosen destination.

Mapbox

  1. First, get the current user location coordinates. It is used as the starting point of the calculated route.

    guard let userCoordinate = navigationMapView.mapView.location.latestLocation?.coordinate else { return }
  2. Wrap the prepared origin and destination coordinates in the Waypoint class and provide them to the NavigationRouteOptions constructor.

    1let origin = Waypoint(coordinate: userCoordinate)
    2let destination = Waypoint(coordinate: destination)
    3
    4let routeOptions = NavigationRouteOptions(waypoints: [origin, destination], profileIdentifier: .automobileAvoidingTraffic)
  3. Calculate routes with the given options. The result is returned via the closure provided as a parameter.

    1Directions.shared.calculate(routeOptions) { _, result in
    2 switch result {
    3 case .failure:
    4 // failure case
    5 break
    6 case let .success(response):
    7 guard let route = response.routes?.first else { return }
    8 self.drawRoute(route: route)
    9 }
    10}
  4. Finally, draw a calculated route on the map. You can also mark waypoints on the route.

    1private func drawRoute(route: Route) {
    2 navigationMapView.show([route])
    3 navigationMapView.showWaypoints(on: route)
    4}

TomTom SDK

The TomTom Routing API allows the app to easily calculate a route between two points, add waypoints, and specify other route properties. The requested Route can then be drawn on the map. Detailed information about routing in the TomTom SDK can be found in the Routing module documentation. A good place to start is the Quickstart guide.

  1. Before using the TomTom Routing service you need to provide a valid TomTom API key.
    RoutingOnlineService.routingKey = Keys.ROUTING_KEY
  2. Initialize TomTomRoutingService. It is the entry point for the routing service.
    routingService = TomTomRoutingService()
  3. Build a routing request using RoutingOptionsBuilder. You can configure the request to fit your requirements. Read more about routing properties in the TomTom Routing API documentation.
    1let amsterdamCoordinate = CLLocationCoordinate2DMake(52.3764527, 4.9062047)
    2let berlinCoordinate = CLLocationCoordinate2DMake(52.5069751, 13.3631919)
    3let hagueCoordinate = CLLocationCoordinate2DMake(52.078663, 4.288788)
    4let hagueAddress = Address()
    5let hagueWaypoint = ItineraryPoint(coordinate: hagueCoordinate, name: "The Hague itinerary point", address: hagueAddress)
    6routingOptions = RoutingOptionsBuilder(origin: amsterdamCoordinate, destination: berlinCoordinate)
    7 .with(waypoints: [hagueWaypoint])
    8 .with(routeType: .efficient)
    9 .with(travelMode: .bus)
    10 .build()
  4. Perform a request using the previously-built RoutingOptions as a parameter. A result is returned via the provided closure.
    1routingService.planRoute(options: routingOptions) { result in
    2 switch result {
    3 case let .success(response):
    4 if let route = response.routes?.first {
    5 self.drawRoute(route)
    6 }
    7 case .failure:
    8 // failure case
    9 break
    10 }
    11}
  5. Finally, use the Route calculated by the routing service to draw it on the map. The RouteOptions class can be used to customize the appearance of the route. Read more about adding a route to the map here.
    1private func drawRoute(_ route: TomTomSDKRoute.Route) {
    2 let routeOptions = RouteOptions(coordinates: route.geometry)
    3 _ = try? tomTomMap.addRoute(routeOptions)
    4}

The last part of this tutorial is about navigation along the previously-calculated route. Navigation shows the current speed limit, the next maneuver, and the estimated time and distance remaining for the trip.

Mapbox SDK

In the Mapbox SDK for iOS, navigation can be completely handled by NavigationViewController. It provides a separate view with the map and UI components, showing the information required for navigation such as maneuvers, estimated time, and voice instructions.

let navigationViewController = NavigationViewController(for: routeResponse, routeIndex: 0, routeOptions: routeOptions)

Then present the initialized NavigationViewController.

present(navigationViewController, animated: true, completion: nil)

If you want to observe navigation updates such as arrival, rerouting, or progress, you have to use NavigationViewControllerDelegate.

TomTom SDK

This tutorial contains a superficial description of navigation. If you want to learn more about how to use the Navigation SDK, you can read the guides. A good place to start is the Navigation quickstart guide.

In the TomTom SDK for iOS, navigation is handled in a slightly different way than in the Mapbox SDK. It does not provide an additional controller for navigation, meaning that you have to make visual adjustments on your own.

The entry point to interact with navigation is the Navigation class. Therefore it has to be initialized before starting a trip session. Navigation can be configured using NavigationConfigurationBuilder. It requires a valid TomTom API key and the RoutingService that is needed for route replanning during navigation. You can set custom engines such as LocationEngine. Read more about Navigation modularization in the Navigation modularization document.

1let locationEngine = DefaultCLLocationEngine()
2let navigationConfiguration = NavigationConfigurationBuilder(
3 navigationKey: Keys.NAVIGATION_KEY,
4 locationEngine: locationEngine,
5 routingService: routingService
6).build()
7navigation = Navigation(configuration: navigationConfiguration)

Once navigation has been initialized and the Route has been calculated, you can proceed with starting it. To use turn-by-turn navigation, provide the RoutePlan property to the navigation start method. It requires the calculated Route and RouteOptions that will be used in route replanning.

let routePlan = RoutePlan(route: route, routingOptions: routingOptions)
navigation.start(routePlan: routePlan)

For a better user experience, change the location indicator to a chevron and set the appropriate camera tracking mode.

tomTomMap.cameraTrackingMode = .followWithHeading
tomTomMap.locationIndicatorType = .navigationChevron

The last recommended step is to set the map-matched location engine from the Navigation to the TomTomMap. It matches the raw location updates to the route and provides a predicted location to give the best user experience when GPS may lose signal.

tomTomMap.setCustomLocationEngine(navigation.mapMatchedLocationEngine)

To get more information from the navigation session, its progress, instructions, or replanning can be observed using TomTomNavigationDelegate. Set it to the Navigation.delegate property. It may also be useful to implement the navigation UI components.