Migrate to the latest version

VERSION 0.34.2
PUBLIC PREVIEW

This tutorial contrasts how to implement core functionality in the current TomTom SDKs and in the legacy version. The tutorial covers:

Project setup

  1. Configure the project as described in the project setup guide.

  2. Import the necessary frameworks using the following instructions, based on your preferred package manager. This tutorial uses the TomTomSDKMapDisplay, TomTomSDKRoutePlannerOnline, and TomTomSDKSearch modules.

    Swift Package Manager
    1. Open your App’s target and navigate to General > Frameworks, Libraries, and Embedded Content.
    2. Add the following TomTomSDK libraries from the provided code snippet. Once the project is set up, import the mentioned frameworks into your code.
    1import TomTomSDKCommon
    2import TomTomSDKMapDisplay
    3import TomTomSDKRoutePlanner
    4import TomTomSDKRoutePlannerOnline
    5import TomTomSDKSearch
    6import TomTomSDKSearchOnline
    CocoaPods
    1. Add the following modules to your project’s Podfile:
      1TOMTOM_SDK_VERSION = '0.34.2'
      2
      3target 'YourAppTarget' do
      4 use_frameworks!
      5 pod 'TomTomSDKMapDisplay', TOMTOM_SDK_VERSION
      6 pod 'TomTomSDKRoutePlannerOnline', TOMTOM_SDK_VERSION
      7 pod 'TomTomSDKSearch', TOMTOM_SDK_VERSION
      8end
    2. Install the dependencies by executing the following commands in the project directory:
      pod repo-art update tomtom-sdk-cocoapods
      pod install --repo-update
    3. Import the following frameworks:
      1import TomTomSDKCommon
      2import TomTomSDKMapDisplay
      3import TomTomSDKRoutePlanner
      4import TomTomSDKRoutePlannerOnline
      5import TomTomSDKSearch
      6import TomTomSDKSearchOnline
  3. 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 SEARCH_KEY = "YOUR_SEARCH_API_KEY"
    4 static let ROUTING_KEY = "YOUR_ROUTING_API_KEY"
    5}

Displaying a map

Legacy SDK

To display a map in the TomTom Legacy SDK, you must perform the following steps:

  1. Add the TTMapView field to the class.

    private var mapView: TTMapView!
  2. Initialize the TTMapView in a LegacySDKViewController class, using TTMapConfiguration to provide a valid TomTom API key and other optional properties.

    1let mapConfig = TTMapConfigurationBuilder.create()
    2 .withMapKey(Keys.MAPS_KEY)
    3 .build()
    4mapView = TTMapView(frame: view.frame, mapConfiguration: mapConfig)
  3. Add the initialized TTMapView to the parent view.

    view.addSubview(mapView)
  4. At this point the map will be displayed. Map initialization is an asynchronous process. To perform operations on the map, it must be fully initialized. To be informed when it is ready to be used, set TTMapViewDelegate to the TTMapView and implement the TTMapViewDelegate.onMapReady(_:) method.

    mapView.delegate = self
    1func onMapReady(_: TTMapView) {
    2 showUserLocation()
    3}

Current TomTom SDKs

Map initialization in the new TomTom SDKs is very similar.

  1. Prepare a property to hold the TomTomMap instance.

    private var map: TomTomMap!
  2. Set the TomTom API key to MapsDisplayService before using the map.

    MapsDisplayService.apiKey = Keys.MAPS_KEY
  3. Initialize the MapView object, which displays a map in the view hierarchy. It can be used to configure the map.

    1let mapView = MapView(frame: view.frame)
    2let amsterdam = CLLocationCoordinate2DMake(52.36218, 4.88891)
    3mapView.cameraUpdate = CameraUpdate(position: amsterdam)
  4. Add the initialized MapView to the parent view.

    view.addSubview(mapView)
  5. At this point, the map is displayed. To interact with the map it has to be fully initialized. Use MapViewDelegate to observe when the map is ready to be used. It gives the TomTomMap instance of the initialized map, which is used to perform operations such as adding a marker or drawing a route.

    mapView.delegate = self
    1func mapView(_ mapView: MapView, onMapReady _: TomTomMap) {
    2 showUserLocation(mapView: mapView)
    3}
Globe view

Showing user location

To access user location you must 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 immediately fail and the map is unable to get the user location.

Legacy SDK

To show user location in the Legacy SDK you must set the TTMapView.isShowsUserLocation property.

mapView.isShowsUserLocation = true

If you then want to show the center button, you must add the TTControlView to the TTMapView and initialize a default center button.

1let controlView = TTControlView(frame: mapView.frame)
2controlView.mapView = mapView
3mapView.addSubview(controlView)
4controlView.initDefaultCenterButton()

Current TomTom SDKs

To show the user location on the map, change the TomTomMap.locationIndicatorType to either LocationIndicator.userLocation(scale:) or LocationIndicator.navigationChevron(scale:).

By default, the CLLocationManager is used as the source of location updates. However, you can also provide your own source. You can read more about user location in the Showing the user’s location guide.

map.locationIndicatorType = .userLocation

By default the center button is hidden. To show it you must change its visibility using MapView.

mapView.currentLocationButtonVisibilityPolicy = .visible

This part of the tutorial describes a simple fuzzy search implementation. For more detailed information about searches see the Search module documentation, for example the Search quickstart guide.

With both SDKs, you need to use an UITextField to get the search term from the user and the UITableView to display search results. However, their implementation is outside the scope of this tutorial. This tutorial only covers functionality within the SDK.

Legacy SDK

  1. The entry point to the Search services is through the TTSearch interface. Create the property TTSearch and initialize it with a valid TomTom API key.

    private var searchService: TTSearch!
    searchService = TTSearch(key: Keys.SEARCH_KEY)
  2. The fuzzy search request is built using TTSearchQuery. To initialize it use its builder - TTSearchQueryBuilder.

    1let searchQuery = TTSearchQueryBuilder.create(withTerm: query)
    2 .withMinFuzzyLevel(2)
    3 .withTypeAhead(true)
    4 .build()
  3. Use the prepared TTSearchQuery to perform the request. The results are returned using a closure that was provided to the request method.

    1searchService.search(with: searchQuery) { response, error in
    2 if let error = error {
    3 self.handleAPIError(error.localizedDescription)
    4 } else if let results = response?.results {
    5 self.handleSearchResults(results)
    6 }
    7}

Current TomTom SDKs

  1. In current TomTom SDKs, the entry point to the search service is the OnlineSearchFactory. Prepare a property to hold Search instance provided by OnlineSearchFactory.
    private var search: Search!
  2. The online search service requires an API key. You can get an API key by following the instructions in the quickstart guide). After obtaining the API key, initialize the search service:
    search = OnlineSearchFactory.create(apiKey: "YOUR_API_KEY")
  3. Fuzzy search requires a SearchOptions. It provides the request with the necessary parameters.
    let searchOptions = SearchOptions(query: query)
  4. Use the prepared SearchOptions to perform the fuzzy search request. The results are returned using the closure that was provided to the request method.
    1search.search(options: searchOptions) { result in
    2 switch result {
    3 case let .success(searchResponse):
    4 self.handleSearchResults(searchResponse.results)
    5 case let .failure(error):
    6 self.handleAPIError(error.localizedDescription)
    7 }
    8}

Adding a marker

This section explains how to add a marker at a selected location using each of the SDKs.

Legacy SDK

To add a marker to the map, create a TTAnnotation object to specify its properties. Then add the TTAnnotation to the TTMapView via TTAnnotationManager.

1func displayMarker(at position: CLLocationCoordinate2D) {
2 let annotation = TTAnnotation(coordinate: position)
3 mapView.annotationManager.add(annotation)
4}

Current TomTom SDKs

Adding a marker works in a similar way in the new TomTom SDKs. Configure the marker using the MarkerOptions class. The initialized MarkerOptions object has to be added to the TomTomMap. NOTE: If adding a marker fails, an exception will be thrown.

The initialized MarkerOptions object has to be added to the TomTomMap.

Read more about markers in the Markers guide.

1func displayMarker(at position: CLLocationCoordinate2D) {
2 let markerOptions = MarkerOptions(coordinate: position, pinImage: UIImage(named: "marker_pin_image")!)
3 let marker = try? map.addMarker(options: markerOptions)
4}
center

Drawing a route

The last part of this tutorial explains how to plan a route between two locations and draw it on the map.

Legacy SDK

  1. The entry point for routing service in the Legacy SDK is the TTRoute interface. Initialize it with your valid TomTom API key.

    private var routeService: TTRoute!
    routeService = TTRoute(key: Keys.ROUTING_KEY)
  2. Build and perform the request. Specify the route parameters using TTRouteQuery. Use TTRouteQueryBuilder to apply the chosen parameters. Then provide the configured specification to the routing call. Possible routes are returned inside the closure provided to the request method.

    1let routeQuery = TTRouteQueryBuilder.create(withDest: destinationLocation, andOrig: departureLocation)
    2 .withRouteType(.fastest)
    3 .withTravelMode(.car)
    4 .build()
    5routeService.plan(with: routeQuery) { result, error in
    6 if let error = error {
    7 self.handleAPIError(error.localizedDescription)
    8 } else if let result = result {
    9 self.handleRouteResults(result)
    10 }
    11}
  3. Draw the calculated route on the map. You can define the appearance of the route using the TTMapRouteStyleBuilder class. The TTMapRoute is a representation of the path to add to the map. You must provide it with a list of coordinates. You can also specify the design, but this is optional. All the routes will then be shown in the route overview.

    1guard let route = result.routes.first else { return }
    2let routeStyle = TTMapRouteStyleBuilder()
    3 .withFill(.red)
    4 .build()
    5let mapRoute = TTMapRoute(coordinatesData: route, with: routeStyle, imageStart: nil, imageEnd: nil)
    6mapView.routeManager.add(mapRoute)
    7mapView.routeManager.showAllRoutesOverview()

Current TomTom SDKs

  1. In the current TomTom SDKs the entry point to the routing service is the OnlineRoutePlanner class. Prepare a property to hold its instance.
    private var routePlanner: OnlineRoutePlanner!
  2. Before accessing the Online RoutePlanner you must initialize the OnlineRoutePlanner object with a TomTom API key.
    routePlanner = OnlineRoutePlanner(apiKey: Keys.ROUTING_KEY)
  3. Build and perform the route request. The request requires departure and destination coordinates. You can also provide additional parameters. Add them all using the RoutePlanningOptions struct and then use the object to perform the routing request. As with the legacy SDK, routing results are returned in the provided closure. You can read more about routing in the Planning a route guide.
    1let itinerary = Itinerary(origin: departure, destination: destination)
    2let routingOptions: RoutePlanningOptions
    3do {
    4 routingOptions = try RoutePlanningOptions(
    5 itinerary: itinerary,
    6 costModel: CostModel(routeType: .fast),
    7 vehicle: Car()
    8 )
    9} catch {
    10 print("Invalid planning options: \(error.localizedDescription)")
    11 return
    12}
    13
    14routePlanner.planRoute(options: routingOptions, onRouteReady: nil, completion: { result in
    15 switch result {
    16 case let .success(routingResponse):
    17 self.handleRoutingResponse(routingResponse)
    18 case let .failure(error):
    19 self.handleAPIError(error.localizedDescription)
    20 }
    21})
  4. Use the result of the call to draw a route on the map. To do this, get the route that you want to draw from the RoutePlanningResponse. Use the Route to build a RouteOptions object. This is also the place to specify visual properties for the route. Then add the RouteOptions to the TomTomMap. NOTE: If adding a route to the map failed an error is thrown.

When you display all of the routes, you can also specify the padding from the edges of the map. You can read more about adding a route to the map in the Routes guide.

+

1guard let route = routingResponse.routes?.first else { return }
2var routeOptions = RouteOptions(coordinates: route.geometry)
3routeOptions.color = .red
4_ = try? map.addRoute(routeOptions)
5map.zoomToRoutes(padding: 50)
Adding a route

Next steps

Since you have learned how to implement core functionality in the current TomTom SDKs and in the Legacy SDK, here are recommendations for the next steps: