Force locale for reverseGeocodeLocation in iOS

1.3k views Asked by At

I'm looking for a solution similar to these two questions

But I want to be able to get a non-localized version of address and locality. In my add, when doing reverse geocoding on a non-latin localized device geocoding service returns CLPlacemark which already contains a localized version of address. For instance in Geneva, when using iPhone in Russian, I'm getting

"Площадь Пленпале" instead of "Place de Plainpalais"

which is probably cool but nonetheless confusing since street names aren't in cyrillic. Also, I'm unable to submit a localized version of the address to another API to find an itinerary. So is there a way to force a locale in reverseGeocodeLocation or briefly trick the OS into thinking locale language is set to something other?

Also, doing something like this just before the request doesn't seem to work, since it requires app restart

NSUserDefaults.standardUserDefaults().setObject("fr", forKey: "AppleLanguages"   
NSUserDefaults.standardUserDefaults().synchronize()
2

There are 2 answers

0
kernelpanic On

It turns out modifying UserDefaults was not possible (at least I found no viable solution to do that), so I had to use external reverse geocoder to what I wanted (force locale). Here's one using Google API and Alamofire and SwiftyJSON, wrapped in with a nice completionHandler to get the address when geocoding is done

func getReversePositionFromGoogle(latitude:Double, longitude:Double, completionHandler: (JSON?, NSError?) -> ()) {
    var parameters = ["latlng":"\(latitude), \(longitude)", "sensor": true, "language": "fr"]
    Alamofire.request(.GET, "http://maps.google.com/maps/api/geocode/json", parameters: parameters as? [String : AnyObject])
        .responseJSON(options: NSJSONReadingOptions.AllowFragments) { (request, response, responseObject, error) -> Void in
            let json = JSON(responseObject!)
            completionHandler(json, error)
    }
}
0
deevee On

I know this is old thread, by someone may be looking for updated solution like me.

Tested with Swift 4, iOS 11

You can force to get geocoding results in chosen locale by setting extra argument: preferredLocale: Locale.init(identifier: "en_US").

CLGeocoder().reverseGeocodeLocation(location, preferredLocale: Locale.init(identifier: "en_US"), completionHandler: {(placemarks, error) -> Void in
    print(location)

    if error != nil {
        print("Reverse geocoder failed with error" + error!.localizedDescription)
        return
    }

    if placemarks!.count > 0 {
        let pm = placemarks![0]
        print(pm.administrativeArea!, pm.locality!)
    }
    else {
        print("Problem with the data received from geocoder")
    }
})