6

In my interface I'm showing the display name of a locale with this:

[[NSLocale currentLocale] displayNameForKey: NSLocaleIdentifier value: identifier]

But this gives the display name using the locale of the system which is not always the same as the locale of the app. For example, if I set my system in French and my app doesn't have a French localisation, it will give a French display name in an English interface. Instead I'd like to have an English display name in an English interface so I don't mix the languages.

Mansfield
  • 14,445
  • 18
  • 76
  • 112
Jef
  • 2,134
  • 15
  • 17
  • does [this potentially related question](http://stackoverflow.com/questions/1522210/always-returns-en-us-not-users-current-language) help you out at all? – Michael Dautermann Jan 08 '12 at 19:57
  • well, I could get the most preferred language my app supports of `[NSLocale preferredLanguages]` to determine which gets used but that's not the ideal solution I think... – Jef Jan 08 '12 at 20:12

2 Answers2

3

I'm not sure if this is what you want... But this is a great way to see what language/localization your app is running in:

[[NSBundle mainBundle] preferredLocalizations]

If you app supports both English and French languages, it will return an array of both in the preferred order. On testing, the one at 0 seems to be the xib that is loaded and running.

saluce
  • 13,035
  • 3
  • 50
  • 67
snwbuni
  • 46
  • 1
3

You should create a plist file which you localise, in your plist store the correct locale identifier for the corresponding localisation, when you use your snippet of code, you should load the locale from that localised plist file and use that to get the display name.

That way your locale will always correspond to the on screen interface language. I needed to do this for some dates I wanted to format, and not rely on the system as the calendar format could be set in another language to the system...

hope that helps...

enter image description here

- (NSDictionary*)getLocalizedCalendarStrings{
    NSString* plistPath = [[NSBundle mainBundle] pathForResource:@"calendar" ofType:@"plist"]; // will return the path of the plist in the right language-specific .lproj directory)
    NSDictionary* calendar = [NSDictionary dictionaryWithContentsOfFile:plistPath];
    return calendar;    
}

And use it like so:

NSDictionary * calendar = [self getLocalizedCalendarStrings];
NSString * localeIdentifier = [calendar objectForKey:@"locale_identifier"];
[[NSLocale currentLocale] displayNameForKey: NSLocaleIdentifier value: localeIdentifier]

To avoid the risk of those locale strings being entered being misspelt etc, or if you would like a better code oriented solution, you could of course use a property named "default_language" as a BOOL in the plist and set it to YES only for english, in your code just check this value and if it is NO, then get the device locale, should it be YES, then you know that the app is either in english because that is the device setting, or in english because it doesn't support the current locale of the device and therefore has fallen back onto english by default... so should "default_language" be YES, hard code the locale to en_US, or en_UK if you're patriotic brit...

Something along the lines of this example might solve your problem, a category for NSLocale, but of course this would make you need to have a localised plist for each language you support...

@implementation NSLocale (AppLocale)

+(NSString*)applicationCurrentLocale{
    NSString* plistPath = [[NSBundle mainBundle] pathForResource:@"currentLocale" ofType:@"plist"];
    NSDictionary* currentLocaleData = [NSDictionary dictionaryWithContentsOfFile:plistPath];

    if([[currentLocaleData objectForKey:@"english_default"] boolValue] == YES){
        return @"en_US";
    }else{
        NSString * deviceLocaleIdentifier = [[NSLocale currentLocale] localeIdentifier];
        return [[NSLocale currentLocale] displayNameForKey:NSLocaleIdentifier value:deviceLocaleIdentifier];
    }
}

@end
Daniel
  • 23,129
  • 12
  • 109
  • 154
  • This is a possibility, however in my eyes quite an ugly one. It's better than putting all the languages in Localizable.strings but not as good as a code-only solution. If no other answers will be given then I'll accept this one. – Jef Jan 08 '12 at 20:25
  • Understood, what the real challenge is here, is that you need to be aware of the locale of the app, not the device, since if you arrive into the app with a device set to french, but your app only supports english and spanish, the app locale so to speak would default to english, but the device is french. Therefore I believe that should such an option not be available in the Cocoa API, you wouldn't have any other option but to go through localised files for this. – Daniel Jan 08 '12 at 20:50
  • You could of course use a property named "default_language" as a BOOL in the plist and set it to YES only for english, in your code just check this value and if it is NO, then get the device locale, should it be YES, then you know that the app is either in english because that is the device setting, or in english because it doesn't support the current locale of the device and therefore has fallen back onto english by default... so should "default_language" be YES, hard code the locale to en_US, or en_UK if you're patriotic brit... hope that angle of thought helps – Daniel Jan 08 '12 at 20:55