kCLErrorDomain error 2 after geocoding repeatedly with CLGeocoder
Asked Answered
P

4

39

I have a search bar in my application that the user can type an address into, and it will come up with the geocoded result. The result updates as the user types, according to the following code:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
    ...
    if (self.geocoder.geocoding) [self.geocoder cancelGeocode];
    [self.geocoder geocodeAddressString:searchText completionHandler:^(NSArray *placemarks, NSError *error) {
        if (error != nil) {
            NSLog(@"ERROR during geocode: %@", error.description);
            return;
        }
        //update the view
    }];
}

This works for the first few characters the user enters into the search field. However, after the user types more characters repeatedly, the geocoder starts giving the following error (which I know means that there was a problem with the network):

ERROR during geocode: Error Domain=kCLErrorDomain Code=2 "The operation couldn’t be completed. (kCLErrorDomain error 2.)"

The geocoder does not work again until the entire ViewController is reloaded. Why could this be happening, and what can I do to resolve it?

Pavonine answered 25/7, 2013 at 19:47 Comment(0)
H
72

I believe the reason is the following:
Apple's geocoder does not answer every request in the same way. Instead, the first requests from a certain device are answered quickly, but if the device has sent say 100 requests or more, the answers arrive slower and slower or requests are not answered at all, which might cause your error.
When you reload the view controller, this simply takes time, and the geocoding server is more willing to answer again. Essentially, you cannot do anything about it, since the geocoder sever wants to protect itself from being overloaded by requests from a single device. You simply had to limit the number of requests that you send there.
BTW: The docs say "you should not send more than one geocoding request per minute".

Horsemint answered 25/7, 2013 at 20:30 Comment(7)
Oh yeah, I didn't notice that line in the docs. Makes perfect sense.Pavonine
Sure wish there was a grace period of a week or two while developing : (Balcom
You can actually wait a couple of seconds after this error then try again and it works perfectly fineSpherulite
How long do you have to wait until this error goes away? My test device has been returning this error for days now.Sulfonation
I am sorry, I can't remember. What I do remember is that I could send about 30 requests very fast, and received an answer immediately, before the response stopped for a while. But it stopped only for something like half a minute. Maybe the server enforces this 1/sec on average...Chandless
How to add a delay then?Darcie
Well, I did this 7 years ago, and maybe the server characteristics have changed since then. But I remember that that the first 30 (or so) requests were answered very quickly, but then you had to wait some time (maybe 20 sec?) before the next requests were answered successfully. I guess, you simply have to try it out.Chandless
L
5

Note that this same error is returned when the device is offline.

Langley answered 25/12, 2018 at 14:14 Comment(1)
That's all I knew about this error and getting it when online threw me off so badly :/Pew
D
2

I had this problem while picking location for messenger application. My solution was to introduce delay of 3 seconds, after user stop panning map, before geocoder call. To ensure that user want exactly that location.

Dictionary answered 18/1, 2018 at 10:55 Comment(0)
H
0

I was using 3 delegate methods

func mapView(_ mapView: GMSMapView, willMove gesture: Bool)

func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition)

func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition)

And I was calling the reverse geolocation API in each of the methods. I got triggered the error message.

The error mainly because you are requesting the reverse geolocation API multiple times and more frequently.

How?

-> When you are about to start dragging, the first delegate method fires

-> When I was dragging the view, the camera is being changed, so the second delegate method is being fired and requesting geolocation API

-> When the camera is idle, the third delegate method is fired.

For my case, I had to show the location data in a label, like Uber set on the map, and I analyzed I need the data actually when the camera position is idle. Like I want to get the data of 10KM distance place, do I need the intermediate 9KM data?

so I removed the geolocation call from the first and second delegate method and kept only in the 3rd one. I was setting Loading.. in the label when the delegate methods got fired.

Fetching data in the background thread, because I don't want to hang up the main thread for this.

Also kept a 1-second delay before fetching, just for keeping a separation between the 2 API calls.

Health answered 26/2, 2021 at 17:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.