Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CLPlacemark.locality, value changes if the device language is different

Tags:

ios

clgeocoder

I uses CLGeocoder to decode the CLLocation from longitude/latitude to place names. It works fine. But there is still one thing bothers me. When i set the device language to English, the result of the code below:

- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
       fromLocation:(CLLocation *)oldLocation{
       /* We received the new location */
       NSLog(@"Latitude = %f", newLocation.coordinate.latitude);
       NSLog(@"Longitude = %f", newLocation.coordinate.longitude);
       [self.geoCoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray* placemarks, NSError* error){
           MKPlacemark *placemarker = [placemarks objectAtIndex:0];
           NSLog(@"%@",placemarker.locality);
       }];
      [self.locationManager stopUpdatingLocation];

}

is displayed in english, like : chengdu.

when i change the device language to Chinese,

placemarker.locality

returns a Chinese character value.

But what i really want is that it will always return an English character value (no Chinese character value). I guess this is something related to the locale. Can anyone help on this? Thanks.

like image 664
David L Avatar asked Nov 13 '12 10:11

David L


3 Answers

Usually, it is not a good practice to mess with user locales. If the device language is set to Chinese is because the user want to read Chinese characters so, why do you want to show him in English when he already told you that he want Chinese?

Anyway, if for any reason you need to force english, you can trick the geoCoder which uses the standardUserDefaults first language so you can do something like this just before calling the geoCoder method:

[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"en", nil] forKey:@"AppleLanguages"];

This way, geoCoder will give you all the information in english.

However, this will change the user preferences so it is a best approach to give them back to where they were:

NSMutableArray *userDefaultLanguages = [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"en", nil] forKey:@"AppleLanguages"];

[self.geoCoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray* placemarks, NSError* error){
       MKPlacemark *placemarker = [placemarks objectAtIndex:0];
       NSLog(@"%@",placemarker.locality);
   }];

[[NSUserDefaults standardUserDefaults] setObject:userDefaultLanguages forKey:@"AppleLanguages"];

As I said, you should really think why you need this, but if you really need this, that would work.

like image 118
adepablor Avatar answered Oct 04 '22 13:10

adepablor


I found a nice solution

NSString *country = placemark.ISOcountryCode;

This will return the exact country no matter your locale is. For example country will be @"US" instead of @"United States"

like image 44
Alejandro Luengo Avatar answered Oct 04 '22 13:10

Alejandro Luengo


From ios 11 you can pass a preferredLocale parameter to geocoder reverseGeocodeLocation method.

In Swift:

geocoder.reverseGeocodeLocation(
  location: CLLocation,
  preferredLocale: Locale?,
  completionHandler: {}
)

A preferredLocale value example:

Locale(identifier: "en_US")
like image 28
el_quick Avatar answered Oct 04 '22 13:10

el_quick