-1

Dear Advanced Programmers,

Could you please assist a fairly new programmer into editing this code. Seems that the new version of Xcode does not support the below code and displays the error:

 **"Contextual closure type '(Directions.Session, Result<RouteResponse, DirectionsError>) -> Void' (aka '((options: DirectionsOptions, credentials: DirectionsCredentials), Result<RouteResponse, DirectionsError>) -> ()') expects 2 arguments, but 3 were used in closure body"** 

The code is copied directly from the mapbox documentation website. Any form of assistance would be appreciated. Thanks in advance.

func getRoute(from origin: CLLocationCoordinate2D,
              to destination: MGLPointFeature) -> [CLLocationCoordinate2D]{
    
    var routeCoordinates : [CLLocationCoordinate2D] = []
    let originWaypoint = Waypoint(coordinate: origin)
    let destinationWaypoint = Waypoint(coordinate: destination.coordinate)
    
    let options = RouteOptions(waypoints: [originWaypoint, destinationWaypoint], profileIdentifier: .automobileAvoidingTraffic)
    
    _ = Directions.shared.calculate(options) { (waypoints, routes, error) in    
        
        guard error == nil else {
            print("Error calculating directions: \(error!)")
            return
        }
        
        guard let route = routes?.first else { return }
        routeCoordinates = route.coordinates!
        self.featuresWithRoute[self.getKeyForFeature(feature: destination)] = (destination, routeCoordinates)
    }
    return routeCoordinates
}

1 Answers1

2

Please, developers, learn to read error messages and/or the documentation.

The error clearly says that the type of the closure is (Directions.Session, Result<RouteResponse, DirectionsError>) -> Void (2 parameters) which represents a session (a tuple) and a custom Result type containing the response and the potential error.

You have to write something like

_ = Directions.shared.calculate(options) { (session, result) in 

    switch result {
       case .failure(let error): print(error)
       case .success(let response): 
          guard let route = response.routes?.first else { return }
          routeCoordinates = route.coordinates!
          self.featuresWithRoute[self.getKeyForFeature(feature: destination)] = (destination, routeCoordinates)
    }   
}

Apart from the issue it's impossible to return something from an asynchronous task, you have to add a completion handler for example

func getRoute(from origin: CLLocationCoordinate2D,
          to destination: MGLPointFeature, 
          completion: @escaping ([CLLocationCoordinate2D]) -> Void) {

and call completion(route.coordinates!) at the end of the success case inside the closure

vadian
  • 274,689
  • 30
  • 353
  • 361