2017-10-12 15 views
0

Je rencontre des problèmes lorsque j'essaie d'appeler la fonction .calculate trouvée dans iOS MapKit. Je comprends que cette fonction s'exécute sur un thread distinct de mon thread principal, mais je ne sais pas comment mettre à jour la valeur de walkingTime avant de retourner le contrôle au thread principal.Retard de fonction asynchrone rapide

class RouteManager { 

    static let shared = RouteManager() 
    var initialWalkingTime: Double! 
    var finalWalkingTime: Double! 
    private init() { 

    } 

    func calculateWalkingTime(
       from givenLocation: CLLocation, 
       to givenStop: CLLocation, 
       completion: @escaping (_ double: Double?, _ error: Error?) ->()) { 

     let sourcePlacemark = MKPlacemark(coordinate: givenLocation.coordinate) 
     let sourceMapItem = MKMapItem(placemark: sourcePlacemark) 
     let destinationPlacemark = MKPlacemark(coordinate: givenStop.coordinate) 
     let destinationMapItem = MKMapItem(placemark: destinationPlacemark) 
     var walkingTime: Double? 

     let request = MKDirectionsRequest() 
     request.source = sourceMapItem 
     request.destination = destinationMapItem 
     request.transportType = .walking 
     request.requestsAlternateRoutes = false 
     let directions = MKDirections(request: request) 

     directions.calculate { response, error in 
      if let route = response?.routes.first { 
       walkingTime = (route.expectedTravelTime/60) 
      } 
      completion(walkingTime, error) 
     } 
    } 

    func setupRoutes(from initialLocation: CLLocation, to finalLocation: CLLocation) { 

     let startingLocation = BusManager.shared.startingLocation.location 
     let endingLocation = BusManager.shared.endingLocation.location 

     calculateWalkingTime(from: initialLocation, to: startingLocation) {(walkingTime, error) in 
      guard let walkingTime = walkingTime, error == nil else {return} 
      self.initialWalkingTime = walkingTime 
     } 

     calculateWalkingTime(from: endingLocation, to: finalLocation) {(walkingTime, error) in 
      guard let walkingTime = walkingTime, error == nil else {return} 
      self.finalWalkingTime = walkingTime 
     } 
    } 
} 

Fondamentalement mon RouteManager.shared.initialWalkingTime et RouteManager.shared.finalWalkingTime sont utilisés sur mon interface je besoin afin qu'ils soient mis à jour avant de quitter ma fonction calculateWalkingTime.

Comment procéder?

Répondre

0

En supposant que le calcul assez court, il est probablement bien nicher juste les:

func setupRoutes(from initialLocation: CLLocation, to finalLocation: CLLocation) { 

    let startingLocation = BusManager.shared.startingLocation.location 
    let endingLocation = BusManager.shared.endingLocation.location 

    calculateWalkingTime(from: initialLocation, to: startingLocation) {(firstWalkingTime, error) in 
     guard let firstWalkingTime = firstWalkingTime, error == nil else {return} 

     calculateWalkingTime(from: endingLocation, to: finalLocation) {(secondWalkingTime, error) in 
      guard let secondWalkingTime = secondWalkingTime, error == nil else {return} 
      self.initialWalkingTime = firstWalkingTime 
      self.finalWalkingTime = secondWalkingTime 
     } 
    } 
} 

Notez que votre conception, vous devriez probablement faire self.initialWalkingTime et self.finalWalkingTime optionals parce qu'il est un processus fail-mesure.

+0

Je crois que le problème est plus que le '.calculate' prend plus de temps que la fonction' calculateWalkingTime', donc quand le contrôle revient à la fonction 'setupRoutes', il initialise' initialWalkingTime' et 'finalWalkingTime' à' nil' plutôt que mon Valeur souhaitée. –

+0

Ce n'est pas comme ça que ça fonctionne ... votre fonction 'setupRoutes' se terminera avant que le bloc d'achèvement de' calculateWalkingTime' ne soit appelé. – PeejWeej

+0

Je suppose que ma question est de savoir comment j'obtiendrais la valeur de 'calculateWalkingTime' sauvé dans' initialWalkingTime' et 'finalWalkingTime' avant que' setupRoutes' ne soit terminé. –