Как получить текущий код языка с помощью Swift?

Я хочу получить код языка устройства (en, es...) в своем приложении, написанном с помощью Swift. Как это получить?

Я пытаюсь это:

var preferredLanguages : NSLocale!
let pre = preferredLanguages.displayNameForKey(NSLocaleIdentifier, value: preferredLanguages)

Но это возвращает ноль.


person user3739367    schedule 05.07.2014    source источник


Ответы (14)


В Свифт 3

let langStr = Locale.current.languageCode
person Vadim Motorine    schedule 12.10.2016
comment
должно быть: Locale.current.identifier, но Locale.current.languageCode для китайского языка, он всегда возвращает 'zh', но его нужно различать zh-HK и т. д. - person iXcoder; 17.06.2017
comment
@ User9527 Из-за того, что вы, скорее всего, не включили локализацию для этого языка в настройках своего проекта. - person Kirill Kudaev; 12.03.2019
comment
Не удается присвоить значение типа «String» типу «Язык?» - person Puji Wahono; 04.07.2019
comment
Насколько я заметил, он вернет фактический язык, установленный в «Настройки» -> «Основные» -> «Язык и регион» -> «Язык iPhone», ТОЛЬКО ЕСЛИ локализация для этого языка включена в вашем проекте в разделе «Проект» -> «Локализации». В противном случае это язык разработки. - person Huralnyk; 19.11.2019
comment
Как мне создать исполняемый двоичный файл, который выводит это значение, используя только версию xcode для командной строки? - person HappyFace; 18.10.2020

Важно различать язык приложения и язык устройства (приведенный ниже код соответствует Swift 3).

Возвращает язык устройства:

let locale = NSLocale.current.languageCode

Возвращает язык приложения:

let pre = Locale.preferredLanguages[0]
person raed    schedule 25.07.2017
comment
Я не понимаю разницы между языком устройства и языком приложения. У вас есть какие-либо документы о разнице? - person Jeremiah; 13.04.2018
comment
Язык @Jeremiah будет содержать язык устройства, например, язык вашего устройства настроен на французский. Pre будет содержать предпочтительный язык пользователя (или приложения), например: ваше приложение поддерживает только китайский язык, поэтому вы можете установить китайское приложение на французском устройстве. Надеюсь, я разъяснил это 4 u - person raed; 22.04.2018
comment
Когда вы говорите, что устройство настроено на французский язык, что вы имеете в виду? Кажется, что если я изменю язык в настройках на что-то отличное от английского, он будет представлен в предпочитаемых языках, но не в языковом коде. Как изменяется код языка? - person Jeremiah; 24.04.2018
comment
Если вы измените настройки на что-то другое, кроме английского, вы получите его значение в NSLocale.current.languageCode. - person raed; 24.04.2018
comment
Разве не наоборот? Если моим языком разработки приложения является EN, и я работаю на устройстве, настроенном на DE, для которого я локализовал приложение, результат будет следующим: Locale.current.languageCode: de Locale.current.identifier: de_DE Locale.preferredLanguages[0]: de Когда моим языком разработки приложения является EN, и я работаю на устройстве, настроенном на FR, для которого у меня есть не локализовал приложение, результат: Locale.current.languageCode: en Locale.current.identifier: en_FR Locale.preferredLanguages[0]: fr - person Arjen Hiemstra; 12.11.2018
comment
@ArjenHiemstra то, что я вижу здесь, это то, что вы всегда получаете язык устройства в предпочитаемых языках [0], возможно, вы неправильно видите свой язык разработки! Чтобы принудительно использовать язык приложения, вы должны сделать это через схему, проверьте URL-адрес среды .com/lean-localization/ - person raed; 12.11.2018
comment
@ArjenHiemstra Если вам нужна дополнительная помощь, мы должны сделать это иначе, чем здесь! Думать о чем-то. - person raed; 12.11.2018
comment
Я настроил схемы для проверки вышеизложенного. 1 схема с Германией/Германией и 1 схема с Францией/Францией. Языком, в котором работает приложение, является DE, если у меня есть локализация DE, и EN (мой язык разработки), если у меня нет локализации для устройства. По крайней мере, это то, что я вижу? - person Arjen Hiemstra; 19.11.2018
comment
@ArjenHiemstra, вы можете дать мне доступ к вашему коду? Ссылка на гитхаб! - person raed; 25.11.2018
comment
@raed Ты воспроизвел? - person Arjen Hiemstra; 29.11.2018
comment
@ArjenHiemstra Извините за опоздание, это странно, но я всегда получаю DE для всех параметров, даже если мое устройство EN или FR! - person raed; 30.11.2018
comment
Это неправильно еще по одной причине: iOS 13.1 вводит настройку языка для каждого приложения, и Locale.preferredLanguages[0] не принимает это во внимание, тогда как Locale.current.languageCode учитывает. - person Oleksii Nezhyborets; 03.10.2019
comment
Я пытался выяснить, как выполняется языковая настройка iOS 13.1 для каждого приложения, и не могу понять? Мое приложение поддерживает 12 языков и устанавливается языковыми настройками устройства. Похоже, я должен просмотреть список Locale.preferredLanguages ​​сверху и посмотреть, попаду ли я в него, если не на английский. Но нужно ли объявлять языки (возможности) в коде приложения? - person Jan Bergström; 31.10.2019
comment
Для меня внутри консоли отладки (lldb). И Locale.preferredLanguages[0], и NSLocale.current.languageCode отображают один и тот же ответ en, но мой iPhone не настроен на английский. У вас есть этому объяснение? - person Michel; 13.11.2019
comment
Я думаю, что это больше не работает в новых версиях iOS! @Мишель - person raed; 14.11.2019

Свифт 4 и 5:

Locale.current.languageCode
person Bogdan Bystritskiy    schedule 30.05.2018
comment
Не удается присвоить значение типа «String» типу «Язык?» - person Puji Wahono; 04.07.2019
comment
Попробуйте Locale(identifier: Locale.current.identifier); - person koen; 29.10.2019
comment
Locale.autoupdatingCurrent.languageCode также доступен - person C. Bess; 26.02.2020

Swift 3, 4, 4.2 и 5

Locale.current.languageCode не компилируется регулярно. Потому что вы не выполнили локализацию для своего проекта.

У вас есть два возможных решения

1) String(Locale.preferredLanguages[0].prefix(2)) Он корректно возвращает язык телефона.

Если вы хотите получить тип en-En, вы можете использовать Locale.preferredLanguages[0]

2) Выберите Project(MyApp)->Project (not Target)-> нажмите кнопку + в Localizations, затем добавьте нужный язык.

person Ali Ihsan URAL    schedule 08.10.2018
comment
Это действительно интересно! Где вы прочитали решение номер один? Не удается найти эту информацию в документации Apple - person kuzdu; 21.05.2019

В Свифт 3:

NSLocale.current.languageCode
person mazorati    schedule 07.10.2016

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

NSLocale.currentLocale().objectForKey(NSLocaleLanguageCode)!
person Benknopf    schedule 30.07.2015

быстро 3

let preferredLanguage = Locale.preferredLanguages[0] as String
print (preferredLanguage) //en-US

let arr = preferredLanguage.components(separatedBy: "-")
let deviceLanguage = arr.first
print (deviceLanguage) //en
person Bassant Ashraf    schedule 06.07.2017
comment
Отдельный код языка и код страны - глючит. Ваш код сломается в некоторых случаях, таких как «zh-Hans-US». - person Evilisn Jiang; 29.10.2019
comment
let langStr = Locale.preferredLanguages.first!это то, что я сделал, рецензируя этот пост. Это работает, и я сравниваю свои языки с langStr.lowercased().contains("es"), например, для всех вариантов испанского языка. - person Ian Ortega; 10.01.2020

TL;DR:

Используйте Bundle.main.preferredLocalizations[0], чтобы получить язык, на котором в данный момент отображается пользовательский интерфейс вашего приложения. Не используйте Locale.current, поскольку он описывает формат региона (время, валюта, расстояние и т. д.) и не имеет ничего общего с языком.

Подробный ответ:

четкий ответ о том, как получить код языка(!) для языка, на котором отображается пользовательский интерфейс вашего приложения, исходит от инженера Apple Куинна Эскимоса, и я цитирую/перефразирую для Swift:

Locale.current возвращает текущую локаль, то есть значение, заданное в разделе Настройки › Общие › Язык и регион › Форматы регионов. Это не имеет никакого отношения к языку, на котором работает ваше приложение. Вполне разумно и на самом деле довольно часто для пользователей в полевых условиях устанавливать для своих локали и языка «конфликтующие» значения. Например, для носителя английского языка, проживающего во Франции, язык должен быть установлен на английский, но он может выбрать французский язык (таким образом, он получит метрические веса и меры, время 24 и т. д.).

Язык, на котором работает ваше приложение, определяется параметром языка, то есть Настройки › Общие › Язык и регион › Предпочтительный порядок языков. Когда система запускает ваше приложение, она берет этот список языков (предпочтительный список) и сопоставляет его со списком языков, на которые локализовано ваше приложение (список приложений). Первый язык в предпочтительном списке, который существует в списке приложений, — это язык, выбранный для приложения. Это то, что вы найдете в первой записи массива preferredLocalizations основного пакета.

Название языка из кода

Чтобы получить удобочитаемое название языка из его кода, вы можете использовать это:

let langCode = Bundle.main.preferredLocalizations[0]
let usLocale = Locale(identifier: "en-US")
var langName = ""
if let languageName = usLocale.localizedString(forLanguageCode: langCode) {
    langName = languageName
}
        

Это даст вам английское название текущего языка пользовательского интерфейса.

person Johannes Fahrenkrug    schedule 09.03.2021
comment
Также может быть полезно рассмотреть возможность использования Locale.current вместо Locale(идентификатор: en-US), чтобы название языка было на самом языке. Français вместо французского например - person Moxy; 01.06.2021
comment
@Moxy Отличное предложение, спасибо! - person Johannes Fahrenkrug; 02.06.2021

вы можете использовать приведенный ниже код, он отлично работает с быстрым 3

var preferredLanguage : String = Bundle.main.preferredLocalizations.first!
person Amr Angry    schedule 12.10.2017
comment
Это тот, который на самом деле все еще работает со Swift 4! Спасибо! - person Alex Wally; 17.11.2017

Я хочу отслеживать язык, выбранный пользователем в приложении «Настройки», каждый раз, когда пользователь запускает мое приложение, которое еще не локализовано (мое приложение только на английском языке). Я принял эту логику:

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

    enum Language: String {
    
    case none = ""
    case en = "English"
    case fr = "French"
    case it = "Italian"
    
    } // add as many languages you want
    
  2. создайте пару расширений для Locale

    extension Locale {
    
        static var enLocale: Locale {
    
            return Locale(identifier: "en-EN")
        } // to use in **currentLanguage** to get the localizedString in English
    
        static var currentLanguage: Language? {
    
            guard let code = preferredLanguages.first?.components(separatedBy: "-").last else {
    
                print("could not detect language code")
    
                return nil
            }
    
            guard let rawValue = enLocale.localizedString(forLanguageCode: code) else {
    
                print("could not localize language code")
    
                return nil
            }
    
            guard let language = Language(rawValue: rawValue) else {
    
                print("could not init language from raw value")
    
                return nil
            }
            print("language: \(code)-\(rawValue)")
    
            return language
        }
    }
    
  3. Когда вам нужно, вы можете просто использовать расширение

    if let currentLanguage = Locale.currentLanguage {
        print(currentLanguage.rawValue)
        // Your code here.
    }
    
person Miniapps    schedule 05.05.2018
comment
Спасибо @Syscall :) - person Miniapps; 05.05.2018
comment
Расширение понравилось :). Разве не имеет смысла возвращать none, если он не может как-то читать. потому что таким образом это значение может быть использовано для создания некоторого значения. - person Alix; 15.08.2018

В Swift вы можете получить локаль, используя.

let locale = Locale.current.identifier
person yo2bh    schedule 08.03.2019

Locale.current.languageCode возвращает мне неправильный код, поэтому я использую эти расширения:

extension Locale {
    static var preferredLanguageCode: String {
        let defaultLanguage = "en"
        let preferredLanguage = preferredLanguages.first ?? defaultLanguage
        return Locale(identifier: preferredLanguage).languageCode ?? defaultLanguage
    }

    static var preferredLanguageCodes: [String] {
        return Locale.preferredLanguages.compactMap({Locale(identifier: $0).languageCode})
    }
}
person ChikabuZ    schedule 06.02.2020

Свифт 5.4:

let languagePrefix = Locale.preferredLanguages[0]
print(languagePrefix)
person Makwan BK    schedule 09.11.2020

Это то, что я использую в Swift 5 Xcode 11:

Внутри переменных класса:

let languagePrefix = Bundle.main.preferredLocalizations.first?.prefix(2)

Это приходит как строка. Он возвращает 2 символа, то есть en, es, de...

Из этого я могу легко определить, какой язык отображать:

 if languagePrefix == "es" { self.flipCard.setTitle("última carta", for: .normal) }
 if languagePrefix == "en" { self.flipCard.setTitle("Last Card", for: .normal) }

Если вы хотите получить полную информацию о языке, удалите ?.prefex(2)

person Brian M    schedule 12.07.2020