Получить текущий язык устройства в iOS?

394

Я хотел бы показать текущий язык, который использует пользовательский интерфейс устройства. Какой код я бы использовал?

Я хочу, чтобы это было как NSString в полностью записанном формате. (Не @ "en_US" )

EDIT: для тех, кто путешествует, здесь есть много полезных комментариев, так как ответ эволюционировал с новыми выпусками iOS.

  • 1
    Это встроено в NSLocale . Смотри мой ответ.
  • 13
    Комментарий iOS9: обратите внимание на тот факт, что по какой-то странной причине Apple изменила формат, возвращаемый [NSLocale preferredLanguages] . раньше он был разделен подчеркиванием (например, en_US ), но теперь он был заменен на тире: en-US
Показать ещё 3 комментария
Теги:
cocoa-touch
nslocale

29 ответов

727
Лучший ответ

Представленные решения фактически вернут текущую область устройства - не выбранный в данный момент язык. Это часто одно и то же. Однако, если я нахожусь в Северной Америке, и я задал свой язык японскому языку, мой регион по-прежнему будет английский (Соединенные Штаты). Чтобы получить выбранный язык, вы можете:

NSString * language = [[NSLocale preferredLanguages] firstObject];

Это вернет двухбуквенный код для выбранного в данный момент языка. "en" для английского, "es" для испанского, "de" для немецкого и т.д. Дополнительные примеры см. в этой записи в Википедии (в частности, колонке 639-1):

Список кодов ISO 639-1

Тогда это простой вопрос о преобразовании двух буквенных кодов в строку, которую вы хотите отобразить. Поэтому, если он "en", отобразите "английский".

Надеюсь, это поможет кому-то, кто хочет различать регион и выбранный язык.

ИЗМЕНИТЬ

Стоит процитировать информацию заголовка из 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

Люди, интересующиеся языком приложений, смотрят ответ @mindvision

  • 2
    Именно то, что я искал. У меня была такая же проблема, когда регион не совпадает с языком.
  • 12
    плохой ответ: возвращает zh-Hans для китайского языка, который не является ISO-кодом.
Показать ещё 20 комментариев
262

Выбранный ответ возвращает текущий язык устройства, но не тот язык, который используется в приложении. Если вы не указали локализацию в своем приложении для предпочтительного языка пользователя, используется первая локализация, упорядоченная по предпочитаемому пользователю порядку.

Чтобы обнаружить текущий язык, выбранный в пределах ваших локализаций, используйте

[[NSBundle mainBundle] preferredLocalizations];

Пример:

NSString *language = [[[NSBundle mainBundle] preferredLocalizations] objectAtIndex:0];

Swift:

let language = NSBundle.mainBundle().preferredLocalizations.first as NSString
  • 0
    Отлично, это то, что меня также интересовало. Проверено и работает правильно!
  • 5
    идеально! это позволяет мне создавать локализованные пути к удаленным ресурсам только с теми языками, которые мое приложение поддерживает в предпочтительном порядке.
Показать ещё 5 комментариев
76

Решение для iOS 9:

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

language = "en-US"

NSDictionary *languageDic = [NSLocale componentsFromLocaleIdentifier:language];

languageDic будет иметь необходимые компоненты

NSString *countryCode = [languageDic objectForKey:@"kCFLocaleCountryCodeKey"];

countryCode = "US"

NSString *languageCode = [languageDic objectForKey:@"kCFLocaleLanguageCodeKey"];

languageCode = "en"

  • 5
    kCFLocaleLanguageCodeKey - это определенная константа, которую вы можете использовать вместо создания собственной строки.
  • 2
    Это работает и для iOS 8, спасибо
61

Это, вероятно, даст вам то, что вы хотите:

NSLocale *locale = [NSLocale currentLocale];

NSString *language = [locale displayNameForKey:NSLocaleIdentifier 
                                         value:[locale localeIdentifier]];

Он отобразит имя языка в самом языке. Например:

Français (France)
English (United States)
  • 30
    неправильный ответ: это возвращает язык, а не язык, который может быть другим ...
  • 4
    Это определенно неправильно, например, если вы установили язык в настройках телефона на английский, а формат Region - на немецкий, Германия, в приведенном выше примере возвращается «German». Тем не менее язык телефона установлен на английский.
Показать ещё 1 комментарий
27

Изображение 5421 Принятые, а остальные ответы на все не учитывают, что предпочтительный язык может быть другим языком, чем язык устройства.

Язык устройства - это язык, на котором представлены элементы операционной системы и приложения Apple.

предпочтительный язык - это язык, на котором пользователь хотел бы локализовать приложения. Apple предоставляет только ограниченный набор переводов. Если предпочтительным языком является один язык, на котором Apple переводила свои приложения, это также будет язык устройства. Однако, если пользователь предпочитает язык, для которого Apple не предоставляет переводы, устройство и предпочтительные языки не будут соответствовать. Язык устройства не будет в первой позиции в списке предпочтительных языков.

Следующая функция перейдет в список предпочтительных языков и проверьте, есть ли перевод в инфраструктуре Apple. Первым языком для перевода является язык устройства. Функция вернет код языка.

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
}

Это работает, если предпочтительный список языков:

  • Африкаанс (iOS не переведена на африкаанс)
  • Испанский (язык устройства)

предпочтительный список языков может быть отредактирован в: Settings.app → Общие → Язык и регион → Порядок предпочтительного языка


Вы можете использовать код языка устройства и перевести его в название языка. Следующие строки будут печатать язык устройства на языке устройства. Например, "Español", если устройство настроено на испанский.

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)
    }
} 
  • 2
    Это должен быть правильный ответ.
  • 0
    NSBundle(forClass: UIView.self) я понимаю, инициализируя ваш экземпляр пакета с помощью NSBundle(forClass: UIView.self) вы пытаетесь предоставить наиболее конкретный язык для данного представления. Однако, используя это, я столкнулся с проблемой, когда для данного класса язык не был возвращен. Я изменил инициализацию на NSBundle.mainBundle() и получил ожидаемый код языка.
Показать ещё 9 комментариев
14

Я использую этот

    NSArray *arr = [NSLocale preferredLanguages];
for (NSString *lan in arr) {
    NSLog(@"%@: %@ %@",lan, [NSLocale canonicalLanguageIdentifierFromString:lan], [[[NSLocale alloc] initWithLocaleIdentifier:lan] displayNameForKey:NSLocaleIdentifier value:lan]);
}

игнорировать утечку памяти..

и результат

2013-03-02 20:01:57.457 xx[12334:907] zh-Hans: zh-Hans 中文(简体中文)
2013-03-02 20:01:57.460 xx[12334:907] en: en English
2013-03-02 20:01:57.462 xx[12334:907] ja: ja 日本語
2013-03-02 20:01:57.465 xx[12334:907] fr: fr français
2013-03-02 20:01:57.468 xx[12334:907] de: de Deutsch
2013-03-02 20:01:57.472 xx[12334:907] nl: nl Nederlands
2013-03-02 20:01:57.477 xx[12334:907] it: it italiano
2013-03-02 20:01:57.481 xx[12334:907] es: es español
  • 0
    просто для любопытства, где здесь утечка памяти?
  • 0
    Утечка - [[[NSLocale alloc] initWithLocaleIdentifier: lan].
Показать ещё 1 комментарий
12

Перевод языковых кодов, таких как ru_US на английский (США), является встроенной функцией NSLocale и NSLocale, неважно, где вы получаете язык коды от. Таким образом, на самом деле нет оснований для реализации собственного перевода, как предполагает принятый ответ.

// Example code - try changing the language codes and see what happens
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en"];
NSString *l1 = [locale displayNameForKey:NSLocaleIdentifier value:@"en"];
NSString *l2 = [locale displayNameForKey:NSLocaleIdentifier value:@"de"];
NSString *l3 = [locale displayNameForKey:NSLocaleIdentifier value:@"sv"];
NSLog(@"%@, %@, %@", l1, l2, l3);

Отпечатки: Английский, Немецкий, Шведский

  • 1
    На самом деле, вы должны использовать [NSLocale autoupdatingCurrentLocale] для инициализации вашего экземпляра локали. Таким образом, названия языков будут отображаться на родном языке пользователя. Например, шведский станет Свенска.
7

Даже лучший способ получить текущий язык устройства. Попробуем это ниже кода -

NSLog(@"Current Language - %@", [[NSLocale preferredLanguages] firstObject]);

Предлагается Abizern на здесь

7

Вы можете использовать метод displayNameForKey:value: 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"]);

Это напечатает:

français (France)
anglais (États-Unis)

Если вы укажете один и тот же идентификатор языка для метода initWithLocaleIdentifier:, а также метод displayNameForKey:value:, он даст вам собственное имя языка. Я обнаружил, что если вы удалите код страны и используете только fr и en, то он также опустит страну из отображаемого имени (по крайней мере, в Mac OS X, не уверен в iOS).

5

Я попытался найти правильное решение для себя. Когда я использую Locale.preferredLanguages.first, был возвращен предпочтительный язык из настроек вашего приложения.

Если вы хотите узнать язык с пользовательских настроек устройства, вы должны использовать строку ниже:

Swift 3

let currentDeviceLanguage = Locale.current.languageCode
// Will return the optional String

Чтобы развернуть и использовать, посмотрите на строку ниже:

if let currentDeviceLanguage = Locale.current.languageCode {
    print("currentLanguage", currentDeviceLanguage)

    // For example
    if currentDeviceLanguage == "he" {
        UIView.appearance().semanticContentAttribute = .forceRightToLeft
    } else {
        UIView.appearance().semanticContentAttribute = .forceLeftToRight
    }
}
  • 0
    вам не нужно разворачивать, если вы используете этот Bundle.main.preferredLocalizations [0] как String
5

Swift

Чтобы получить текущий язык устройства

NSLocale.preferredLanguages()[0] as String

Чтобы получить язык приложения

NSBundle.mainBundle().preferredLocalizations[0] as NSString

Примечание:

Он выбирает язык, который вы указали в CFBundleDevelopmentRegion of info.plist

если CFBundleAllowMixedLocalizations истинно в info.plist, тогда возвращается первый элемент CFBundleLocalizations в info.plist

4

Для получения текущего пользовательского устройства используйте следующий код, который он работал у меня.

NSString * myString = [[NSLocale preferredlanguage]objectAtIndex:0];
3

Я использую этот код:

[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]
3

Функция Simple Swift 3:

  @discardableResult
  func getLanguageISO() -> String {
    let locale = Locale.current
    guard let languageCode = locale.languageCode,
          let regionCode = locale.regionCode else {
        return "de_DE"
    }
    return languageCode + "_" + regionCode
  }
3

В Swift:

let languageCode = NSLocale.currentLocale().objectForKey(NSLocaleLanguageCode) as? String
3

Для разработчиков MonoTouch С# используйте:

NSLocale.PreferredLanguages.FirstOrDefault() ?? "en"

Примечание. Я знаю, что это вопрос iOS, но поскольку я разработчик MonoTouch, ответ на этой странице привел меня в правильном направлении, и я решил поделиться результатами.

  • 0
    В настоящее время я использую NSLocale.PreferredLanguages и получаю пустой массив. Я предполагаю, что вы прочитали в документации, что она никогда не может быть пустой, но я нигде не вижу этого?
  • 0
    Нет, честно, это было только мое предположение.
Показать ещё 1 комментарий
2

Swift 3

let locale = Locale.current
let code = (locale as NSLocale).object(forKey: NSLocale.Key.countryCode) as! String?
print(code!)
  • 0
    Добро пожаловать в переполнение стека! Хотя этот фрагмент кода может ответить на вопрос, лучше включить описание того, в чем заключалась проблема, и как ваш код будет решать данную проблему. На будущее, вот некоторая информация о том , как найти отличный ответ на переполнение стека.
2
-(NSString *)returnPreferredLanguage { //as written text

NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
NSArray *preferredLanguages = [defaults objectForKey:@"AppleLanguages"];
NSString *preferredLanguageCode = [preferredLanguages objectAtIndex:0]; //preferred device language code
NSLocale *enLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en"]; //language name will be in English (or whatever)
NSString *languageName = [enLocale displayNameForKey:NSLocaleIdentifier value:preferredLanguageCode]; //name of language, eg. "French"
return languageName;

}
1

Для Swift 3.0 ниже код может быть использован для ответа на ваш вопрос:

 let language = Bundle.main.preferredLocalizations.first! as NSString
1

Если вы хотите получить только один язык, это мой предложенный ответ:

NSString *langplusreg = [[NSLocale preferredLanguages] objectAtIndex:0];
NSString * langonly = [[langplusreg componentsSeparatedByString:@"-"] 
objectAtIndex:0];

В моем случае я просто хотел, чтобы язык Locale не был локальным.

Вывод: Если ваш язык Locale является японским, а региональный регион - Япония, то:

langplusreg = ja-JP

langonly = ja

0

Обновленный ответ для Swift 4

let language = Bundle.main.preferredLocalizations.first
  • 0
    Обратите внимание, что при этом извлекается агрегированный список доступных (поддерживаемых пакетом, т. Е. Вами) и предпочтительных (пользователем) локализаций. NSLocale.preferredLanguages должен возвращать предпочтительные для пользователя, не обращая NSLocale.preferredLanguages на то, что поддерживается пакетом.
0

СВИФТ-4

 // To get device default selected language. It will print like short name of zone. For english, en or spain, es.



let language = Bundle.main.preferredLocalizations.first! as NSString
    print("device language",language)
  • 0
    Обратите внимание, что при этом извлекается агрегированный список доступных (поддерживаемых пакетом, т. Е. Вами) и предпочтительных (пользователем) локализаций. NSLocale.preferredLanguages должен возвращать предпочтительные для пользователя, не обращая NSLocale.preferredLanguages на то, что поддерживается пакетом.
0

Если вы ищете предпочтительный код языка ("en", "de", "es"...) и локализованное предпочтительное имя языка (для текущей локали), здесь простое расширение в Swift:

extension Locale {
static var preferredLanguageIdentifier: String {
    let id = Locale.preferredLanguages.first!
    let comps = Locale.components(fromIdentifier: id)
    return comps.values.first!
}

static var preferredLanguageLocalizedString: String {
    let id = Locale.preferredLanguages.first!
    return Locale.current.localizedString(forLanguageCode: id)!
}

}

0

Очевидно, что решения, полагающиеся, например, на

[[NSLocale preferredLanguages] objectAtIndex:0]

обычно работают нормально и возвращают текущий язык устройства.

Но в некоторых случаях это может ввести в заблуждение:

Если приложение, в которое вы хотите получить это значение, уже изменило язык, например, с помощью такого кода:

NSString *lg = @"en"; // or anything like @"en", @"fr", etc.
[[NSUserDefaults standardUserDefaults] 
    setObject:[NSArray arrayWithObjects:lg, nil]  
    forKey:@"AppleLanguages"]

В этом случае [NSLocale preferredLanguages] фактически возвращает предпочтительный языковой набор (и используется) в этом конкретном приложении, а не на текущий язык устройства!

И... в этом случае единственный способ правильно получить текущий текущий язык устройства (а не тот, который ранее был установлен в приложении), - это сначала очистить ключ @ "appleLanguages" в NSUserDefaults, например:

[[NSUserDefaults standardUserDefaults]removeObjectForKey:@"AppleLanguages"];

Затем [NSLocale preferredLanguages] теперь возвращает правильное значение.

Надеюсь на эту помощь.

0

Как и в iOS 9, если вы просто хотите код языка без кода страны, вам понадобится такая вспомогательная функция - поскольку язык будет содержать код страны.

// gets the language code without country code in uppercase format, i.e. EN or DE
NSString* GetLanguageCode()
{
    static dispatch_once_t onceToken;
    static NSString* lang;
    dispatch_once(&onceToken, ^
    {
        lang = [[[NSLocale preferredLanguages] objectAtIndex:0] uppercaseString];
        NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:@"^[A-Za-z]+" options:0 error:nil];
        NSTextCheckingResult* match = [regex firstMatchInString:lang options:0 range:NSMakeRange(0, lang.length)];
        if (match.range.location != NSNotFound)
        {
            lang = [lang substringToIndex:match.range.length];
        }
    });
    return lang;
}
0

Для Swift 3:

NSLocale.preferredLanguages ​​[0] as String

0

@amir ответ в Swift:

// Get language prefered by user
    let langageRegion = NSLocale.preferredLanguages().first!
    let languageDic = NSLocale.componentsFromLocaleIdentifier(langageRegion)
    let language = languageDic[NSLocaleLanguageCode]
0

Формат двух букв. Apple использует стандарт ISO ISO-3166.

NSString *localeCountryCode = [[NSLocale autoupdatingCurrentLocale] objectForKey:NSLocaleCountryCode];
0

Согласно Apple documentation

NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
NSArray* languages = [defs objectForKey:@"AppleLanguages"];
NSString* preferredLang = [languages objectAtIndex:0];

Ещё вопросы

Сообщество Overcoder
Наверх
Меню