2017-02-09 129 views
1

一次只能发生一个GeoCode请求,它们是异步的,所以我需要在前一个请求完成后立即开始下一个请求。我有这样的工作:Swift:GeoCoding递归异步循环

func one() { 
     let geocoder = CLGeocoder() 
     let one = myPlacesFakeData[0] 

     geocoder.geocodeAddressString(one.address, completionHandler: { (placemarks, error) in 
      if let error = error { 
       print("Unable to Reverse Geocode Location (\(error))") 
      } else { 
       if let placemarks = placemarks, let placemark = placemarks.first { 
        myPlacesFakeData[0].latitude = placemark.location?.coordinate.latitude 
        myPlacesFakeData[0].longitude = placemark.location?.coordinate.longitude 
       } else { 
        print("No Matching Address Found") 
       } 
      } 

      self.two() 
     }) 
    } 

    func two() { 
     let geocoder = CLGeocoder() 
     let two = myPlacesFakeData[1] 

     geocoder.geocodeAddressString(two.address, completionHandler: { (placemarks, error) in 
      if let error = error { 
       print("Unable to Reverse Geocode Location (\(error))") 
      } else { 
       if let placemarks = placemarks, let placemark = placemarks.first { 
        myPlacesFakeData[1].latitude = placemark.location?.coordinate.latitude 
        myPlacesFakeData[1].longitude = placemark.location?.coordinate.longitude 
       } else { 
        print("No Matching Address Found") 
       } 
      } 
      self.three() 
     }) 
    } 

    func three() { 
     let geocoder = CLGeocoder() 
     let three = myPlacesFakeData[2] 

     geocoder.geocodeAddressString(three.address, completionHandler: { (placemarks, error) in 
      if let error = error { 
       print("Unable to Reverse Geocode Location (\(error))") 
      } else { 
       if let placemarks = placemarks, let placemark = placemarks.first { 
        myPlacesFakeData[2].latitude = placemark.location?.coordinate.latitude 
        myPlacesFakeData[2].longitude = placemark.location?.coordinate.longitude 
       } else { 
        print("No Matching Address Found") 
       } 
      } 

     }) 
    } 

但这是贫民窟,并取决于我正在尝试GeoCode正好三个地方。

我想我需要一个递归函数和一个计数器,但我不知道如何写这个。任何帮助将不胜感激。

回答

3

这是一个显示一种方法的操场。您可以使用一个函数,该函数将调用自己并累积结果,一旦所有地址都经过地理编码,最终会调用完成处理程序。错误处理和更好的类型包装你可以做得更好,但这是一个很好的起点!

//: Playground - noun: a place where people can play 

import Cocoa 
import CoreLocation 
import PlaygroundSupport 

PlaygroundPage.current.needsIndefiniteExecution = true 

func geoCode(addresses: [String], results: [CLPlacemark] = [], completion: @escaping ([CLPlacemark]) -> Void) { 
    guard let address = addresses.first else { 
     completion(results) 
     return 
    } 

    let geoCoder = CLGeocoder() 
    geoCoder.geocodeAddressString(address) { placemarks, error in 

     var updatedResults = results 

     if let placemark = placemarks?.first { 
      updatedResults.append(placemark) 
     } 

     let remainingAddresses = Array(addresses[1..<addresses.count]) 

     geoCode(addresses: remainingAddresses, results: updatedResults, completion: completion) 
    } 
} 

let addresses = ["1600 Pennsylvania Ave NW, Washington, DC 20500", "1 Infinite Loop, Cupertino, CA"] 

geoCode(addresses: addresses) { results in 
    print("Got back \(results.count) results") 
} 
+1

安德鲁,非常感谢。完美工作。 –