I\'d like to show the current language that the device UI is using. What code would I use?
I want this as an NSString
in fully spelled out format. (Not
You can use the displayNameForKey:value:
method of NSLocale:
// get a French locale instance
NSLocale *frLocale = [[[NSLocale alloc] initWithLocaleIdentifier:@"fr_FR"] autorelease];
// use it to get translated display names of fr_FR and en_US
NSLog(@"%@", [frLocale displayNameForKey:NSLocaleIdentifier value:@"fr_FR"]);
NSLog(@"%@", [frLocale displayNameForKey:NSLocaleIdentifier value:@"en_US"]);
This will print out:
français (France)
anglais (États-Unis)
If you specify the same locale identifier for the initWithLocaleIdentifier:
and also the displayNameForKey:value:
method, then it will give you the native name of the language. I've discovered that if you remove the country code and use just fr
and en
, that it will also omit the country from the display name (on Mac OS X at least, not sure about iOS).
The accepted, and the other answers all don't take into account that the preferred language can be another language than the device language.
The device language is the language in which operating system elements and Apple apps are presented.
The preferred language is the language the user would like to have apps localized in. Apple only provides a limited set of translations. If the preferred language is one language Apple translated their apps to, it will also be the device language. However if the user prefers a language for which Apple doesn't provide translations the device and preferred languages won't match. The device language will not be on first position in the preferred languages list.
The following function will go through the preferred languages list and check if there is a translation in the Apple frameworks. The first language to have a translation is the device language. The function will return its language code.
func deviceLanguage() -> String? {
let systemBundle: NSBundle = NSBundle(forClass: UIView.self)
let englishLocale: NSLocale = NSLocale(localeIdentifier: "en")
let preferredLanguages: [String] = NSLocale.preferredLanguages()
for language: String in preferredLanguages {
let languageComponents: [String : String] = NSLocale.componentsFromLocaleIdentifier(language)
guard let languageCode: String = languageComponents[NSLocaleLanguageCode] else {
continue
}
// ex: es_MX.lproj, zh_CN.lproj
if let countryCode: String = languageComponents[NSLocaleCountryCode] {
if systemBundle.pathForResource("\(languageCode)_\(countryCode)", ofType: "lproj") != nil {
// returns language and country code because it appears that the actual language is coded within the country code aswell
// for example: zh_CN probably mandarin, zh_HK probably cantonese
return language
}
}
// ex: English.lproj, German.lproj
if let languageName: String = englishLocale.displayNameForKey(NSLocaleIdentifier, value: languageCode) {
if systemBundle.pathForResource(languageName, ofType: "lproj") != nil {
return languageCode
}
}
// ex: pt.lproj, hu.lproj
if systemBundle.pathForResource(languageCode, ofType: "lproj") != nil {
return languageCode
}
}
return nil
}
This works if the preferred language list is:
The preferred language list can be edited in: Settings.app -> General -> Language & Region -> Preferred Language Order
You can than use the device language code and translate it into the language name. The following lines will print the device language in the device language. For example "Español" if the device is set to spanish.
if let deviceLanguageCode: String = deviceLanguage() {
let printOutputLanguageCode: String = deviceLanguageCode
let printOutputLocale: NSLocale = NSLocale(localeIdentifier: printOutputLanguageCode)
if let deviceLanguageName: String = printOutputLocale.displayNameForKey(NSLocaleIdentifier, value: deviceLanguageCode) {
// keep in mind that for some localizations this will print a language and a country
// see deviceLanguage() implementation above
print(deviceLanguageName)
}
}
Even there's a better way to get current device language. Let's try it by below code -
NSLog(@"Current Language - %@", [[NSLocale preferredLanguages] firstObject]);
Suggested by Abizern on here
@amir response in Swift :
// Get language prefered by user
let langageRegion = NSLocale.preferredLanguages().first!
let languageDic = NSLocale.componentsFromLocaleIdentifier(langageRegion)
let language = languageDic[NSLocaleLanguageCode]
Updated answer for Swift 4
let language = Bundle.main.preferredLocalizations.first
The solutions provided will actually return the current region of the device - not the currently selected language. These are often one and the same. However, if I am in North America and I set my language to Japanese, my region will still be English (United States). In order to retrieve the currently selected language, you can do:
NSString * language = [[NSLocale preferredLanguages] firstObject];
This will return a two letter code for the currently selected language. "en" for English, "es" for Spanish, "de" for German, etc. For more examples, please see this Wikipedia entry (in particular, the 639-1 column):
List of ISO 639-1 codes
Then it's a simple matter of converting the two letter codes to the string you would like to display. So if it's "en", display "English".
Hope this helps someone that's looking to differentiate between region and currently selected language.
EDIT
Worth to quote the header information from NSLocale.h:
+ (NSArray *)preferredLanguages NS_AVAILABLE(10_5, 2_0); // note that this list does not indicate what language the app is actually running in; the [NSBundle mainBundle] object determines that at launch and knows that information
People interested in app language take a look at @mindvision's answer