84

I'm in the processes of internationalizing an iPhone app - I need to make programmatic changes to certain views based on what the user's current locale is. I'm going nuts because no matter what the language preference on the iPhone simulator or actual hardware are, locale always evaluates to "en_US":

NSString *locale = [[NSLocale currentLocale] localeIdentifier];
NSLog(@"current locale: %@", locale);

The crazy thing is that the rest of the application behaves as expected. The correct strings are selected from the Localization.strings file and used in the interface, and the correct .xib files for the selected locale are used.

I have also tried the following, to no avail and with the same result:

NSString *locale = [[NSLocale autoupdatingCurrentLocale] localeIdentifier];
NSLog(@"current locale: %@", locale);

Is there something simple I'm missing? A preference or an import perhaps?

What I used to do:

As Darren's answer suggests, the preference I'm looking for is not in NSLocale, rather it is here:

NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
NSArray* languages = [userDefaults objectForKey:@"AppleLanguages"];
NSString* preferredLanguage = [languages objectAtIndex:0];
NSLog(@"preferredLanguage: %@", preferredLang);

Peter's answer seems to be a better solution:

NSArray* preferredLanguages = [NSLocale preferredLanguages];
NSLog(@"preferredLanguages: %@", preferredLanguages);
prairiedogg
  • 6,323
  • 8
  • 44
  • 52

9 Answers9

59

[NSLocale currentLocale] is based on the device's Region Format settings, not the language. If the region is set to United States you will get en_US regardless of which language you're using.

Darren
  • 25,520
  • 5
  • 61
  • 71
  • Thanks Darren, that got me started, I also figured out how to get the current language setting, which is what I was really trying to do. – prairiedogg Oct 06 '09 at 04:06
  • 2
    Hi Prairiedogg,how did you get the current language setting? i have the same problem also..all returns EN value for language. – Zaldy Bughaw Aug 26 '10 at 14:22
  • @ZaldzBugz: something like: NSLocale* locale = [NSLocale currentLocale]; NSString* lang = [locale displayNameForKey:NSLocaleIdentifier value:[[NSLocale preferredLanguages] objectAtIndex:0]]; – powerj1984 Oct 30 '12 at 20:14
  • 3
    this is not the case on iOS 8. iOS 8 will return "de_US" if your language is german and your region is USA. which is what its supposed to do. – odyth Mar 25 '15 at 17:26
  • Is the region auto updated when user, say, goes to Australia? – Nagendra Rao Oct 03 '18 at 14:44
37

Instead of querying defaults directly using an undocumented key, ask the NSLocale class for the array of preferred languages.

Peter Hosey
  • 95,783
  • 15
  • 211
  • 370
  • @PeterHosey I'm also have similar problem regarding current language and tried everything, but none of them worked. So sad... Could you have a look at this, http://stackoverflow.com/questions/26572115/nslocale-preferredlanguages-objectatindex0-always-return-en/26574075#26574075? Thanks! – S1U Oct 26 '14 at 19:07
  • @s1u There's a bug in Xcode 6.1. Check this answer: http://stackoverflow.com/a/26641497/1085556 – Bart van Kuik Nov 14 '14 at 12:43
  • @s1u: Couple of things: (1) There can be multiple preferred languages; there is no single “current language”, and (2) regarding your (deleted) answer, that returns the dominant language of the current locale (a.k.a. region), *not* the user's preferred languages. – Peter Hosey Nov 16 '14 at 19:14
  • 2
    The `AppleLanguages` key isn't undocumented, it's the only documented way to get the user's preferred languages on systems prior to OS X 10.5 (which, these days is very rare, but still, [it **is** documented](https://developer.apple.com/library/mac/qa/qa1391/_index.html)). – dreamlax Apr 30 '15 at 23:13
18

To get the current device language use this instead:

NSString * language = [[NSLocale preferredLanguages] objectAtIndex:0];

As described here: Getting current device language in iOS?

Community
  • 1
  • 1
sust86
  • 1,870
  • 2
  • 18
  • 25
9

For us the issue was that we were overriding the application language and application region in our dev scheme. Make sure that the Application Language is set to System Language in the scheme options (Edit Scheme -> Options).

Simon Bengtsson
  • 7,573
  • 3
  • 58
  • 87
  • Thanks Simon for pointing out this aspect... For testing I had set it to local language & I forgot to change it afterwards. – Ameer Mar 29 '18 at 11:58
  • That was it! Can't believe it was an Xcode setting that was messing it up. – Pedro Oct 10 '18 at 22:40
4

for me, both

NSString *localeString = [[NSLocale currentLocale] localeIdentifier];

and

NSArray *array = [NSLocale preferredLanguages];
self.label.text = array[0];

yield the same result when you're in a simulator.

AlexW
  • 103
  • 1
  • 6
3

I had an issue where formatting month names came out in english on a device set to french language.

My solution was to use this:

    NSLocale *locale = [NSLocale localeWithLocaleIdentifier:[[NSLocale preferredLanguages] objectAtIndex:0] ];
    [self.monthNameFormatter setLocale:locale];
    [self.monthNameFormatter setDateFormat:@"MMMM"];
    [self.monthNameFormatter stringFromDate:myDate];
Ben Clayton
  • 80,996
  • 26
  • 120
  • 129
  • I found that [NSLocale currentLocale] was translating month names to French properly in iOS10 but wasn't in iOS11. Using: NSLocale *locale = [NSLocale localeWithLocaleIdentifier:[[NSLocale preferredLanguages] objectAtIndex:0] ]; fixed the problem. Thanks Ben +1 – birdman Sep 28 '18 at 14:19
2

i found that if i leave "en_US" out , but have a "en" localization that is a copy of "en_US" the simulator automagically starts respecting the language settings, but as soon as "en_US" is an option it always picks it regardless of the settings.

Pants
  • 21
  • 1
1

Question is too old, but this code may help to many:

The main.m should look like this:

    NSString *localecode=[[NSLocale currentLocale] localeIdentifier];
    localecode=[localecode substringToIndex:2]; //en_GB -> en
    NSArray *arr = [NSLocale preferredLanguages];
    NSMutableArray * mutable = [arr mutableCopy];
    NSString *prefered = [mutable firstObject];
    if(![localecode isEqualToString:prefered]){
        if(![prefered isEqualToString:@"es"] && ![prefered isEqualToString:@"en"] && ![prefered isEqualToString:@"pt"]){
            int index = [mutable indexOfObject:@"en"];
            [mutable replaceObjectAtIndex:0 withObject:@"en"];
            [mutable replaceObjectAtIndex:index withObject:prefered];
            [[NSUserDefaults standardUserDefaults] setObject:mutable forKey:@"AppleLanguages"];

        }
        else{
            int index = [mutable indexOfObject:localecode];
            [mutable replaceObjectAtIndex:0 withObject:localecode];
            [mutable replaceObjectAtIndex:index withObject:prefered];
            [[NSUserDefaults standardUserDefaults] setObject:mutable forKey:@"AppleLanguages"];
        }
    }
    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));

What do this? If the current language of the device es Spanish, English or Portuguese use the the application uses the localized strings, by the other hand if the current language is not one of those and is not supported by application is set to English.

cdiazmo
  • 94
  • 1
  • 4
0

It shows the correct locale when on a real iPad. However, the simulator has it´s own iOS which by default is set to en-US. Go to the simulator iOS preferences and switch language & region to the one you want.

That does the trick.

Ronald Hofmann
  • 1,390
  • 2
  • 15
  • 26