Swift:用于地理编码的递归异步循环

COS*_*KER 2 recursion geocode swift

一次只能发生一个 GeoCode 请求,而且它们是异步的,因此我需要在前一个请求完成后立即开始下一个请求。我让它像这样工作:

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")
                }
            }

        })
    }
Run Code Online (Sandbox Code Playgroud)

但这是贫民窟,取决于我正尝试对三个地方进行地理编码。

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

And*_*ter 6

这是一个展示了一种方法的游乐场。您可以使用一个函数来调用自身并累积结果,一旦所有地址都已被地理编码,最终会调用完成处理程序。您可以通过错误处理和更好的类型包装做得更好,但这是一个很好的起点!

//: 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")
}
Run Code Online (Sandbox Code Playgroud)