Você está recebendo o idioma atual do dispositivo no iOS?


431

Gostaria de mostrar o idioma atual que a interface do usuário do dispositivo está usando. Qual código eu usaria?

Eu quero isso como um NSStringformato totalmente explicitado. (Não é "en_US")

EDIT: Para aqueles que seguem adiante, há muitos comentários úteis aqui, pois a resposta evoluiu com os novos lançamentos do iOS.


1
Isso está embutido NSLocale. Veja minha resposta.
— Erik B

15
Comentário iOS9: preste atenção ao fato de que, por algum motivo estranho, a Apple alterou o formato retornado por [NSLocale preferredLanguages]. ele é utilizado para ser separados por sublinhado (por exemplo en_US), mas agora foi mudado para um traço:en-US
— ishahak

7
Mais sobre iOS9: obter [NSLocale preferidoLínguas] em um simulador iOS 8.4 versus 9.0 é também discrepante. No iOS 8.4 é "en" e iOS 9.0 é "en-US"
— Kris Subramanian

Este comentário me ajudou muito! Ficamos com um problema simples, imaginando o que deu errado por aproximadamente 1 hora, até que vi seu comentário.
— Thandasoru 27/10/2015

3
NSLocalepossui métodos componentsFromLocaleIdentifier:e localeIdentifierFromComponents:provavelmente é o caminho certo para lidar com o formato (potencialmente variável).
— Benjohn

Respostas:


808

As soluções fornecidas realmente retornam a região atual do dispositivo - não o idioma atualmente selecionado. Estes são frequentemente o mesmo. No entanto, se eu estiver na América do Norte e definir meu idioma para japonês, minha região ainda será o inglês (Estados Unidos). Para recuperar o idioma atualmente selecionado, você pode:

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

Isso retornará um código de duas letras para o idioma selecionado no momento. "en" para inglês, "es" para espanhol, "de" para alemão etc. Para mais exemplos, consulte esta entrada da Wikipedia (em particular, a coluna 639-1):

Lista de códigos ISO 639-1

Então, basta converter os dois códigos de letras na string que você deseja exibir. Portanto, se for "en", exiba "Inglês".

Espero que isso ajude alguém que está procurando diferenciar entre região e idioma atualmente selecionado.

EDITAR

Vale citar as informações do cabeçalho de 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

As pessoas interessadas no idioma do aplicativo dão uma olhada na resposta da @ mindvision


2
Exatamente o que eu estava procurando. Eu tive o mesmo problema em que região não é a mesma que idioma.
— Jasarien

12
resposta incorreta: retorna zh-Hans para chinês, que não é o código iso.
— Cyrilchampier

2
Os dois primeiros caracteres dão ao país, as coisas depois do traço dão à região, o resto é apenas para reduzi-lo ainda mais (como dialetos locais). zh está listado como o código iso do chinês. Para aqueles que procuram uma linguagem específica, como eu estava, tente o registro IANA
— Xono

3
zh-Hans é a única exceção ou existem outros códigos de idioma que diferem da norma ISO 639-1?
— MPaulo 23/06

57
Aviso: no iOS 9 , o valor de retorno doNSLocale preferredLanguagesalterado. Se antes você estava obtendo apenas "en", no iOS 9 você receberá "en-US" ou "en-JP" etc. Referência: happyteamlabs.com/blog/…
— Dj S

281

A resposta selecionada retorna o idioma atual do dispositivo, mas não o idioma real usado no aplicativo. Se você não fornecer uma localização no seu aplicativo para o idioma preferencial do usuário, será usada a primeira localização disponível, ordenada pela ordem preferida do usuário.

Para descobrir o idioma atual selecionado nas suas localizações, use

[[NSBundle mainBundle] preferredLocalizations];

Exemplo:

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

Rápido:

let language = NSBundle.mainBundle().preferredLocalizations.first as NSString

Excelente, é nisso que eu também estava interessado. Testado e funciona corretamente!
— smileyborg

5
perfeito! ele permite criar caminhos de recursos remotos localizados apenas com os idiomas que meu aplicativo suporta na ordem preferível.
— Yevhen Dubinin

e se quisermos obter o nome completo do idioma depois disso?
— Shabarinath Pabba

Se você deseja obter o nome completo do idioma na localização preferencial, pode usar [[NSLocale aloc] initWithLocaleIdentifier: language] (de cima). Então você tem o código do idioma e pode chamar displayNameForKey.
— Vanessa Forney

87

Solução para iOS 9:

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

idioma = "en-US"

NSDictionary *languageDic = [NSLocale componentsFromLocaleIdentifier:language];

languageDic terá os componentes necessários

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

countryCode = "US"

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

languageCode = "en"


5
kCFLocaleLanguageCodeKey é uma constante definida que você pode usar em vez de criar sua própria sequência.
— SNyamathi 17/02/16

1
NSLocaleLanguageCode = @ "kCFLocaleCountryCodeKey"
— crow

uso NSLocaleCountryCode e NSLocaleLanguageCode para @ "kCFLocaleCountryCodeKey", @ "kCFLocaleLanguageCodeKey", repectively
— cantará

65

Provavelmente, você terá o que deseja:

NSLocale *locale = [NSLocale currentLocale];

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

Ele mostrará o nome do idioma, no próprio idioma. Por exemplo:

Français (France)
English (United States)

31
resposta errada: Isso retorna a localidade, não a língua, que pode ser diferente ...
— cyrilchampier

4
Definitivamente, isso está errado, por exemplo, se você definir o idioma nas configurações do telefone para inglês e o formato Região para, digamos, alemão, Alemanha, o exemplo acima retornará "alemão". Ainda o idioma do telefone está definido para inglês.
— Jake_hetfield # 23/13

2
Isso não está errado. O código do idioma contém informações sobre o idioma e a região. Portanto, no exemplo de @ jake_hetfield, ele não retornaria "alemão", retornaria "inglês (Alemanha)". Isso combinado com a resposta do dreamlab deve ser a resposta correta.
— SeanR

36

AtençãoAs respostas aceitas e as demais respostas não levam em consideração que o idioma preferido pode ser outro idioma que não o idioma do dispositivo .

O idioma do dispositivo é o idioma no qual os elementos do sistema operacional e os aplicativos da Apple são apresentados.

O idioma preferido é o idioma em que o usuário gostaria que os aplicativos fossem localizados. A Apple fornece apenas um conjunto limitado de traduções. Se o idioma preferido for um idioma para o qual a Apple traduziu seus aplicativos, também será o idioma do dispositivo. No entanto, se o usuário preferir um idioma para o qual a Apple não fornece traduções, o dispositivo e os idiomas preferidos não corresponderão . O idioma do dispositivo não estará na primeira posição na lista de idiomas preferidos.

A função a seguir percorrerá a lista de idiomas preferidos e verificará se há uma tradução nas estruturas da Apple. O primeiro idioma a ter uma tradução é o idioma do dispositivo. A função retornará seu código de idioma.

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
}

Isso funciona se a lista de idiomas preferidos for:

  1. Africâner (iOS não é traduzido para Africâner)
  2. Espanhol (idioma do dispositivo)

A lista de idiomas preferidos pode ser editada em : Settings.app -> Geral -> Idioma e região -> Ordem do idioma preferido


Você pode usar o código do idioma do dispositivo e traduzi-lo para o nome do idioma. As linhas a seguir imprimirão o idioma do dispositivo no idioma do dispositivo. Por exemplo "Español" se o dispositivo estiver definido para espanhol.

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)
    }
} 

Meu entendimento é que, ao inicializar sua instância de pacote configurável, NSBundle(forClass: UIView.self)você está tentando fornecer o idioma mais específico para uma determinada exibição. No entanto, usando isso, deparei-me com um problema em que para uma determinada classe um idioma não era retornado. Alterei a inicialização para NSBundle.mainBundle()e retornou o código de idioma esperado.
— palmi

Esclarecimento: Inicializar o pacote com mainBundle()parece ser o recomendado pela Apple como sugerido no cabeçalho NSLocale, // 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.
— palmi

O @Pouria NSBundle.mainBundle()retorna o pacote de aplicativos, enquanto NSBundle(forClass: UIView.self)o pacote UIKit dos sistemas. o método descrito procura por diretórios no pacote configurável. seu pacote de aplicativos conterá apenas os idiomas para os quais você pretende localizar. para determinar o idioma do dispositivo, você precisará verificar o pacote do sistema.
— dreamlab 22/01

1
@Pouria, o problema pode ter sido que o iOS 9 alterou os valores de retorno NSLocale.preferredLanguages(). Eu atualizei a resposta para oferecer suporte ao iOS 9 .
— dreamlab 22/01

Infelizmente, essa abordagem fornece resultados falso-positivos quando você inclui componentes de terceiros, como pods, com localizações que não são compatíveis nas configurações do projeto.
— kokoko

12

Eu uso isso

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

ignorar vazamento de memória ..

e o resultado é

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

só por curiosidade, onde está o vazamento de memória aqui?
— Pode Poyrazoğlu

Vazamento - [[[alocação NSLocale] initWithLocaleIdentifier: lan].
— Pavel

1
Apenas para projetos que não sejam da ARC.
— Josh Hinman

12

A tradução de códigos de idioma como en_US para inglês (Estados Unidos) é um recurso interno do NSLocalee NSLocalenão importa de onde você obtém os códigos de idioma. Portanto, não há realmente nenhuma razão para implementar sua própria tradução, como sugere a resposta aceita.

// 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);

Impressões: Alemão, Inglês, Sueco


1
Na verdade, você deve usar [NSLocale autoupdatingCurrentLocale] para inicializar sua instância de localidade. Dessa forma, os nomes dos idiomas serão exibidos no idioma nativo dos usuários. Por exemplo, o sueco se tornará Svenska.
— Maciej Swic

8

Mesmo existe uma maneira melhor de obter o idioma atual do dispositivo. Vamos tentar pelo código abaixo -

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

Sugerida por Abizern em aqui


7

Você pode usar o displayNameForKey:value:método de 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"]);

Isso será impresso:

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

Se você especificar o mesmo identificador de localidade para initWithLocaleIdentifier:e também o displayNameForKey:value:método, ele fornecerá o nome nativo do idioma. Descobri que, se você remover o código do país e usar just fre en, também omitirá o país do nome de exibição (pelo menos no Mac OS X, não tenho certeza sobre o iOS).


6

Rápido

Para obter o idioma atual do dispositivo

NSLocale.preferredLanguages()[0] as String

Para obter o idioma do aplicativo

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

Nota:

Ele busca o idioma que você forneceu em CFBundleDevelopmentRegion of info.plist

se CFBundleAllowMixedLocalizations for verdadeiro em info.plist , o primeiro item de CFBundleLocalizations em info.plist será retornado


6

Tentei descobrir a solução certa para mim. Quando eu uso, Locale.preferredLanguages.firsté retornado o idioma preferido nas configurações do seu aplicativo.

Se você quiser conhecer o idioma nas configurações do dispositivo do usuário, use a string abaixo:

Swift 3

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

Para desembrulhar e usar, veja a linha abaixo:

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

    // For example
    if currentDeviceLanguage == "he" {
        UIView.appearance().semanticContentAttribute = .forceRightToLeft
    } else {
        UIView.appearance().semanticContentAttribute = .forceLeftToRight
    }
}

você não precisa desembrulhar se usar este Bundle.main.preferredLocalizations [0] como String
— μολὼν.λαβέ

5

Para obter o idioma atual do dispositivo do usuário, use o código a seguir que funcionou para mim.

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

4

iOS13, Swift 5+, WWDC2019 https://developer.apple.com/videos/play/wwdc2019/403/

Os usuários podem selecionar o idioma preferido de um aplicativo independentemente do idioma do SO.

Você pode usar estes:

    // Returns a list of the user's preferred languages.
    // Maybe more than (or none of) your app supports!
    Locale.preferredLanguages

    // a subset of this bundle's localizations, re-ordered into the preferred order
    // for this process's current execution environment; the main bundle's preferred localizations
    // indicate the language (of text) the user is most likely seeing in the UI
    Bundle.main.preferredLocalizations



    // The current running app language
    Bundle.main.preferredLocalizations.first

    // list of language names this bundle appears to be localized to
    Bundle.main.localizations

3

Para os desenvolvedores do MonoTouch C #, use:

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

Nota: Sei que essa é uma pergunta do iOS, mas como sou desenvolvedor do MonoTouch, a resposta nesta página me levou na direção certa e pensei em compartilhar os resultados.


Atualmente, estou usando NSLocale.PreferredLanguages ​​e estou recebendo uma matriz vazia. Suponho que você leu na documentação que talvez nunca esteja vazia, mas não vejo isso em nenhum lugar?
— precisa

Não, honestamente, isso foi apenas uma suposição minha.
— amigos estão dizendo sobre chuck savage

@LarryF Assista a este vídeo: jonas.follesoe.no/2011/07/22/cross-platform-mobile-ndc-2011 É muito informativo sobre como estruturar seus aplicativos de código / multiplataforma.
— mandril Savage

3

Em Swift:

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

3

Swift 3

let locale = Locale.current
let code = (locale as NSLocale).object(forKey: NSLocale.Key.countryCode) as! String?
print(code!)

Bem-vindo ao Stack Overflow! Embora esse trecho de código possa responder à pergunta, é melhor incluir uma descrição de qual era o problema e como o seu código abordará o problema em questão. Para o futuro, aqui estão algumas informações, como obter uma resposta impressionante no Stack Overflow.
— dirtydanee

3

Função Swift 3 simples:

  @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

Se você está procurando o código de idioma preferido ("en", "de", "es" ...) e o nome de idioma preferido localizado (para o local atual), aqui está uma extensão simples no 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)!
}

}


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;

}

2

Se você deseja obter apenas o idioma aqui, é minha resposta sugerida:

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

No meu caso, eu só queria apenas o idioma local e não a região local.

Saída: se o seu idioma local for japonês e a região local for o Japão, então:

langplusreg = ja-JP

langonly = ja


1

resposta @amir em Swift:

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

1

Obviamente, as soluções que dependem, por exemplo, de

[[NSLocale preferredLanguages] objectAtIndex:0]

geralmente funcionam bem e retornam o idioma atual do dispositivo.

Mas pode ser enganoso em alguns casos:

Se o aplicativo no qual você deseja obter esse valor já tiver alterado o idioma, por exemplo, com este tipo de código:

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

Nesse caso, [NSLocale preferênciaLanguages] realmente retorna o conjunto de idiomas preferido (e usado) nesse aplicativo em particular, não o idioma atual do dispositivo!

E ... nesse caso, a única maneira de obter corretamente o idioma atual atual do dispositivo (e não o definido anteriormente no aplicativo), é primeiro limpar a chave @ "appleLanguages" no NSUserDefaults, assim:

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

Então, [NSLocale selectedLanguages] agora retorna o valor correto.

Espero que esta ajuda.


1

Resposta atualizada para o Swift 4

let language = Bundle.main.preferredLocalizations.first

Observe que isso busca a lista agregada de localizações disponíveis (suportadas pelo pacote configurável, você) e preferidas (pelo usuário). NSLocale.preferredLanguagesdeve retornar os preferidos do usuário sem respeitar o que é suportado pelo pacote.
— 11138 Jonny

1

Para o Swift 3.0, o código abaixo pode ser usado para responder à sua pergunta:

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

1

No Swift 4.2 e no Xcode 10.1

let language = NSLocale.preferredLanguages[0]
print(language)//en

0

De acordo com a documentação da Apple

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


0

Para Swift 3:

NSLocale.preferredLanguages ​​[0] como String


0

No iOS 9, se você deseja apenas o código do idioma sem o código do país, deseja esse tipo de função auxiliar - já que o idioma conterá o código do país.

// 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-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)

Observe que isso busca a lista agregada de localizações disponíveis (suportadas pelo pacote configurável, você) e preferidas (pelo usuário). NSLocale.preferredLanguagesdeve retornar os preferidos do usuário sem respeitar o que é suportado pelo pacote.
— Jonny
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.