Language codes to friendly names

Viewed 152

I have a language code, such as "en_US", and I'm trying to get a friendly name from it such as "English".

Here's what I'm doing right now:

Locale.current.localizedString(forLanguageCode: code)

It works, but for languages such as Chinese, it doesn't quite do what I want.

zh-Hans should return "Simplified Chinese", and zh-Hant should return "Traditional Chinese".

However, they both just return "Chinese". How would you get them to return the correct values?

2 Answers

You can use NSLocale's displayName(forKey:value:) instead.

let code = "en_US"
if let identifier = (Locale.current as NSLocale).displayName(forKey: .identifier, value: code) {
    print(identifier) /// English (United States)
}
let code = "zh_Hans"
if let identifier = (Locale.current as NSLocale).displayName(forKey: .identifier, value: code) {
    print(identifier) /// Chinese, Simplified
}

"en_US" is not a language code, it's a locale identifier consisting of the language code "en" and the region code "US". Thus, calling into localizedString(forLanguageCode:) will not work properly. With an identifier (like you have), use localizedString(forIdentifier:):

let identifier = "en_US"
let humanReadableName = 
    Locale.current.localizedString(forIdentifier: identifier) ?? identifier

This also works nicely with identifiers such as zh-Hans which will return "Chinese, Simplified".

Note that I'm suggesting to append ?? identifier at the end because localizedString(forIdentifier:) returns an Optional in case of an invalid identifier where you can fall back to the identifier itself so you don't have to deal with an Optional String.

Related