¿Obtiene el idioma actual del dispositivo en iOS?


431

Me gustaría mostrar el idioma actual que usa la interfaz de usuario del dispositivo. ¿Qué código usaría?

Quiero esto como un NSStringformato completamente enunciado. (No @ "en_US")

EDITAR: Para aquellos que conducen, hay un montón de comentarios útiles aquí, ya que la respuesta ha evolucionado con los nuevos lanzamientos de iOS.


1
Esto está integrado en NSLocale. Mira mi respuesta.
Erik B

15
Comentario de iOS9: preste atención al hecho de que, por alguna extraña razón, Apple ha cambiado el formato devuelto por [NSLocale preferredLanguages]. solía estar separado por un guión bajo (p en_US. ej. ), pero ahora se convirtió en un guión:en-US
ishahak

77
Más información sobre iOS9: Obtener [NSLocale preferredLanguages] en un simulador iOS 8.4 versus un simulador 9.0 también tiene discrepancias. En iOS 8.4 es "en" y iOS 9.0 es "en-US"
Kris Subramanian

¡Este comentario me ayudó mucho! Nos quedamos atrapados con un problema simple preguntándonos qué salió mal durante aproximadamente 1 hora hasta que vi su comentario.
thandasoru

3
NSLocaletiene métodos componentsFromLocaleIdentifier:y localeIdentifierFromComponents:cuáles son probablemente la forma correcta de manejar el formato (potencialmente modificable).
Benjohn

Respuestas:


808

Las soluciones proporcionadas en realidad devolverán la región actual del dispositivo, no el idioma seleccionado actualmente. Estos son a menudo uno y lo mismo. Sin embargo, si estoy en Norteamérica y configuro mi idioma en japonés, mi región seguirá siendo el inglés (Estados Unidos). Para recuperar el idioma seleccionado actualmente, puede hacer:

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

Esto devolverá un código de dos letras para el idioma seleccionado actualmente. "en" para inglés, "es" para español, "de" para alemán, etc. Para obtener más ejemplos, consulte esta entrada de Wikipedia (en particular, la columna 639-1):

Lista de códigos ISO 639-1

Entonces es una simple cuestión de convertir los códigos de dos letras a la cadena que le gustaría mostrar. Entonces, si es "en", muestra "Inglés".

Espero que esto ayude a alguien que busca diferenciar entre la región y el idioma seleccionado actualmente.

EDITAR

Vale la pena citar la información del encabezado 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

Las personas interesadas en el lenguaje de la aplicación echan un vistazo a la respuesta de @ mindvision


2
Exactamente lo que estaba buscando. Tuve el mismo problema donde la región no es lo mismo que el idioma.
Jasarien

12
mala respuesta: devuelve zh-Hans para chino, que no es el código iso.
cyrilchampier

2
Los primeros dos caracteres le dan al país, las cosas después de que el guión le da a la región, el resto es solo para reducirlo aún más (como los dialectos locales). zh aparece como el código iso para chino. Para aquellos que buscan un idioma específico como yo, pruebe el registro de
Xono

3
zh-Hans es la única excepción o hay otros códigos de idioma que difieren del estándar ISO 639-1?
MPaulo

57
Advertencia: en iOS 9 , el valor de retorno delNSLocale preferredLanguagescambio. Si antes solo recibías
Dj S

281

La respuesta seleccionada devuelve el idioma actual del dispositivo, pero no el idioma real utilizado en la aplicación. Si no proporciona una localización en su aplicación para el idioma preferido del usuario, se utiliza la primera localización disponible, ordenada por el orden preferido del usuario.

Para descubrir el idioma actual seleccionado dentro de sus localizaciones use

[[NSBundle mainBundle] preferredLocalizations];

Ejemplo:

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

Rápido:

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

Excelente, esto es lo que también me interesaba. Probado y funciona correctamente!
smileyborg

55
¡Perfecto! me permite construir rutas de recursos remotas localizadas solo con los idiomas que mi aplicación admite en orden preferible.
Yevhen Dubinin

¿Qué pasa si queremos obtener el nombre completo del idioma después de esto?
Shabarinath Pabba

Si desea obtener el nombre completo del idioma de la ubicación preferida, puede usar [[NSLocale alloc] initWithLocaleIdentifier: idioma] (desde arriba). Luego tiene la configuración regional y puede llamar a displayNameForKey.
Vanessa Forney

87

Solución para iOS 9:

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

idioma = "en-US"

NSDictionary *languageDic = [NSLocale componentsFromLocaleIdentifier:language];

languageDic tendrá los componentes necesarios

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

countryCode = "US"

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

languageCode = "en"


55
kCFLocaleLanguageCodeKey es una constante definida que puede usar en lugar de crear su propia cadena.
SNyamathi

1
NSLocaleLanguageCode = @ "kCFLocaleCountryCodeKey"
cuervo

NSLocaleCountryCode uso y NSLocaleLanguageCode para @ "kCFLocaleCountryCodeKey", @ "kCFLocaleLanguageCodeKey", repectively
cuervo

65

Esto probablemente te dará lo que quieres:

NSLocale *locale = [NSLocale currentLocale];

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

Mostrará el nombre del idioma, en el idioma mismo. Por ejemplo:

Français (France)
English (United States)

31
respuesta incorrecta: Esto devuelve la configuración regional, no el lenguaje, que puede ser diferente ...
cyrilchampier

44
Esto definitivamente es incorrecto, por ejemplo, si configura el idioma en la configuración del teléfono en inglés y el formato de región para que digamos alemán, Alemania, el ejemplo anterior devuelve "alemán". Aún así, el idioma del teléfono está configurado en inglés.
jake_hetfield

2
Esto no está mal en absoluto. La configuración regional contiene información de idioma y región. Entonces, en el ejemplo de @ jake_hetfield, no devolvería "alemán", devolvería "inglés (Alemania)". Esto combinado con la respuesta de dreamlab debería ser la respuesta correcta.
SeanR

36

advertenciaLas respuestas aceptadas y las demás no tienen en cuenta que el idioma preferido puede ser otro idioma que el idioma del dispositivo .

El idioma del dispositivo es el idioma en el que se presentan los elementos del sistema operativo y las aplicaciones de Apple.

El idioma preferido es el idioma en el que al usuario le gustaría tener aplicaciones localizadas. Apple solo proporciona un conjunto limitado de traducciones. Si el idioma preferido es un idioma al que Apple tradujo sus aplicaciones, también será el idioma del dispositivo. Sin embargo, si el usuario prefiere un idioma para el que Apple no proporciona traducciones, el dispositivo no coincidirá con los idiomas preferidos . El idioma del dispositivo no estará en la primera posición en la lista de idiomas preferidos.

La siguiente función recorrerá la lista de idiomas preferidos y comprobará si hay una traducción en los marcos de Apple. El primer idioma en tener una traducción es el idioma del dispositivo. La función devolverá su 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
}

Esto funciona si la lista de idiomas preferidos es:

  1. Afrikaans (iOS no está traducido al afrikaans)
  2. Español (idioma del dispositivo)

La lista de idiomas preferidos se puede editar en : Configuración.app -> General -> Idioma y región -> Orden de idioma preferido


Puede usar el código de idioma del dispositivo y traducirlo al nombre del idioma. Las siguientes líneas imprimirán el idioma del dispositivo en el idioma del dispositivo. Por ejemplo "Español" si el dispositivo está configurado en 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)
    }
} 

Tengo entendido que al inicializar su instancia de paquete con NSBundle(forClass: UIView.self)usted está tratando de proporcionar el idioma más específico para una vista determinada. Sin embargo, al usar esto me encontré con un problema en el que para la clase dada no se devolvió un idioma. Cambié la inicialización a NSBundle.mainBundle()y me devolvieron el código de idioma esperado.
palmi

Aclaración: La inicialización del paquete con mainBundle()que parece ser la recomendada por Apple como se sugiere en la cabecera 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

@Pouria NSBundle.mainBundle()devuelve su paquete de aplicaciones, mientras que NSBundle(forClass: UIView.self)devuelve el paquete UIKit del sistema. El método descrito busca directorios en el paquete. su paquete de aplicaciones solo contendrá los correspondientes a los idiomas a los que desea localizar. para determinar el idioma del dispositivo, deberá verificar el paquete del sistema.
dreamlab

1
@Pouria el problema podría haber sido que iOS 9 cambió los valores de retorno de NSLocale.preferredLanguages(). i actualizado la respuesta a apoyar iOS 9 .
dreamlab

@dreamlab, desafortunadamente, este enfoque da resultados falsos positivos cuando incluye componentes de terceros, como pods, con localizaciones que no admite en la configuración del proyecto.
kokoko

12

yo uso esto

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

ignorar pérdida de memoria ..

y el resultado es

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

solo por curiosidad, ¿dónde está la pérdida de memoria aquí?
Can Poyrazoğlu

Fuga - [[[NSLocale alloc] initWithLocaleIdentifier: lan].
Pavel

1
Sin embargo, solo para proyectos que no son ARC.
Josh Hinman

12

La traducción de códigos de idioma como en_US al inglés (Estados Unidos) es una función integrada NSLocaley NSLocaleno le importa de dónde obtiene los códigos de idioma. Entonces, realmente no hay razón para implementar su propia traducción como sugiere la respuesta aceptada.

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

Impresiones: inglés, alemán, sueco


1
En realidad, debe usar [NSLocale autoupdatingCurrentLocale] para inicializar su instancia de configuración regional. De esa forma, los nombres de los idiomas se mostrarán en el idioma nativo de los usuarios. Por ejemplo, el sueco se convertirá en Svenska.
Maciej Swic

8

Incluso hay una mejor manera de obtener el idioma actual del dispositivo. Probémoslo con el siguiente código:

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

Sugerida por Abizern de aquí


7

Puedes usar el 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"]);

Esto imprimirá:

français (France)
anglais tats-Unis)

Si especifica el mismo identificador de configuración regional para el método initWithLocaleIdentifier:y también el displayNameForKey:value:método, le dará el nombre nativo del idioma. Descubrí que si elimina el código de país y usa just frand en, también omitirá el país del nombre para mostrar (al menos en Mac OS X, no estoy seguro acerca de iOS).


6

Rápido

Para obtener el idioma actual del dispositivo

NSLocale.preferredLanguages()[0] as String

Para obtener el idioma de la aplicación

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

Nota:

Obtiene el idioma que ha proporcionado en CFBundleDevelopmentRegion de info.plist

si CFBundleAllowMixedLocalizations es verdadero en info.plist, se devuelve el primer elemento de CFBundleLocalizations en info.plist


6

Traté de encontrar la solución correcta para mí. Cuando utilizo Locale.preferredLanguages.firstse devolvió el idioma preferido de la configuración de su aplicación.

Si desea conocer el idioma de la configuración del dispositivo del usuario, debe usar la siguiente cadena:

Swift 3

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

Para desenvolver y usar mira la línea de abajo:

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

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

no tiene que desenvolverse si usa este Bundle.main.preferredLocalizations [0] como String
μολὼν.λαβέ

5

Para obtener el idioma actual del dispositivo del usuario, use el siguiente código que funcionó para mí.

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

4

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

Los usuarios pueden seleccionar el idioma preferido de una aplicación independientemente del idioma del sistema operativo.

Puedes usar estos:

    // 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 los desarrolladores de MonoTouch C #, use:

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

Nota: Sé que esta fue una pregunta de iOS, pero como soy desarrollador de MonoTouch, la respuesta en esta página me llevó en la dirección correcta y pensé que compartiría los resultados.


Actualmente estoy usando NSLocale.PreferredLanguages ​​y obtengo una matriz vacía. ¿Supongo que has leído en la documentación que puede que nunca esté vacía pero no puedo ver esto en ningún lado?
JFoulkes

No, honestamente eso fue solo una suposición propia.
Chuck Savage

@LarryF Mira este video: jonas.follesoe.no/2011/07/22/cross-platform-mobile-ndc-2011 Es muy informativo sobre cómo estructurar tu código / aplicaciones multiplataforma.
Chuck Savage

3

En 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!)

¡Bienvenido a Stack Overflow! Si bien este código puede responder la pregunta, es mejor incluir una descripción de cuál fue el problema y cómo su código abordará el problema dado. Para el futuro, aquí hay información sobre cómo descifrar una respuesta increíble en Stack Overflow.
dirtydanee

3

Función 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

Si está buscando el código de idioma preferido ("en", "de", "es" ...) y el nombre del idioma preferido localizado (para la ubicación actual), aquí hay una extensión simple en 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

Si desea obtener solo el idioma aquí está mi respuesta sugerida:

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

En mi caso, solo quería el idioma regional, no la región regional.

Salida: si su idioma local es japonés y la región local es Japón, entonces:

langplusreg = ja-JP

langonly = ja


1

Respuesta de @amir en Swift:

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

1

Obviamente, las soluciones que se basan, por ejemplo, en

[[NSLocale preferredLanguages] objectAtIndex:0]

generalmente funciona bien y devuelve el idioma actual del dispositivo.

Pero podría ser engañoso en algunos casos:

Si la aplicación en la que desea obtener este valor ya ha cambiado el idioma, por ejemplo, con este tipo de código:

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

En este caso, [NSLocale preferredLanguages] en realidad devuelve el conjunto de idiomas preferido (y usado) en esta aplicación en particular, ¡no el idioma actual del dispositivo!

Y ... en este caso, la única forma de obtener correctamente el idioma actual del dispositivo actual (y no el establecido previamente en la aplicación), es borrar primero la clave @ "appleLanguages" en NSUserDefaults, de esta manera:

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

Entonces, [NSLocale preferredLanguages] ahora devuelve el valor correcto.

Espero que esto ayude.


1

Respuesta actualizada para Swift 4

let language = Bundle.main.preferredLocalizations.first

Tenga en cuenta que esto busca la lista agregada de localizaciones disponibles (admitidas por el paquete, es decir, usted) y preferidas (por el usuario). NSLocale.preferredLanguagesdebe devolver los preferidos del usuario sin tener en cuenta lo que admite el paquete.
Jonny

1

Para Swift 3.0, el siguiente código se puede utilizar para responder a su pregunta:

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

1

En Swift 4.2 y Xcode 10.1

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

0

De acuerdo con la documentación de Apple

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


0

Para Swift 3:

NSLocale.preferredLanguages ​​[0] como cadena


0

A partir de iOS 9, si solo desea el código de idioma sin código de país, querrá este tipo de función auxiliar, ya que el idioma contendrá el código de 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)

Tenga en cuenta que esto busca la lista agregada de localizaciones disponibles (admitidas por el paquete, es decir, usted) y preferidas (por el usuario). NSLocale.preferredLanguagesdebe devolver los preferidos del usuario sin tener en cuenta lo que admite el paquete.
Jonny
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.