4

Im using MapKit's CLGeocoder().geocodeAddressString() to get the coordinates and county information for a list of addresses. Everything works great as long as the # of requests is under 50. but anything over 50 and im hitting API's limit. Since CLGeocoder calls are asynchronous, i can't easily throttle/control the flow of the calls (calling one address at a time, for instance). How would I do this correctly in the "asynchronous world"? (DISCLAIMER: I'm new to the world of GCD and asynchronous flow control, so I think I might require a more detailed response)

Here's the relevant code:

method of Class Property that calls CLGeocoder on the Property's Adress:

   func initializeCoordinates() {

        let addressForCoords = self.address.getAddress()
        CLGeocoder().geocodeAddressString(addressForCoords, completionHandler: { (placemarks, error) -> Void in
            if error != nil {
                print(error!)
                return
            }
            if placemarks!.count > 0 {
                let placemark = placemarks?[0]
                let location = placemark?.location
                self.coordinates = location?.coordinate

                if let subAdminArea = placemark?.subAdministrativeArea {
                    self.address.county = subAdminArea
                }
            }
        })
    }

and then in the section in the ImportVC that imports all the property's addresses from a textBox (and makes the call to initializeCoordinates method on each Property:

    for line in importText {
        let newAddress = Address()
        let newHouse = Property()

        // parse the tab delimited address for each line of input
        let address = line.components(separatedBy: "\t")
        if address.count == 4 {
            newAddress.street = address[0]
            newAddress.city = address[1]
            newAddress.state = trimState(state: address[2])
            newAddress.zip = address[3]
            newHouse.address = newAddress
            newHouse.initializeCoordinates()
            houses.append(newHouse)
        }
    }

1 Answers1

2

I faced a similar problem recently. Replace your for-loop with a recursive function that calls itself at the end. However the trick is to call its self with a 0.2 second delay. I use 0.4 to be on the safe side. This will increase the waiting time for the user, although we have no choice due to the API limit.

torinpitchers
  • 1,282
  • 7
  • 13