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.