NSLocale currentLocale siempre devuelve "en_US", no el idioma actual del usuario

82

Estoy en el proceso de internacionalizar una aplicación de iPhone; necesito realizar cambios programáticos en ciertas vistas en función de la configuración regional actual del usuario. Me estoy volviendo loco porque no importa cuál sea la preferencia de idioma en el simulador de iPhone o el hardware real, localesiempre se evalúa como "en_US":

NSString *locale = [[NSLocale currentLocale] localeIdentifier];
NSLog(@"current locale: %@", locale);

Lo loco es que el resto de la aplicación se comporta como se esperaba. Las cadenas correctas se seleccionan del archivo Localization.strings y se usan en la interfaz, y se usan los archivos .xib correctos para la configuración regional seleccionada.

También he probado lo siguiente, en vano y con el mismo resultado:

NSString *locale = [[NSLocale autoupdatingCurrentLocale] localeIdentifier];
NSLog(@"current locale: %@", locale);

¿Hay algo simple que me falta? ¿Una preferencia o quizás una importación?

Lo que solía hacer:

Como sugiere la respuesta de Darren, la preferencia que estoy buscando no está en NSLocale, sino aquí:

NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
NSArray* languages = [userDefaults objectForKey:@"AppleLanguages"];
NSString* preferredLanguage = [languages objectAtIndex:0];
NSLog(@"preferredLanguage: %@", preferredLang);

La respuesta de Peter parece ser una mejor solución:

NSArray* preferredLanguages = [NSLocale preferredLanguages];
NSLog(@"preferredLanguages: %@", preferredLanguages);
prairiedogg
fuente

Respuestas:

36

En lugar de consultar los valores predeterminados directamente con una clave no documentada, solicite a la clase NSLocale el conjunto de idiomas preferidos .

Peter Hosey
fuente
@PeterHosey También tengo un problema similar con respecto al idioma actual y probé todo, pero ninguno funcionó. Qué triste ... ¿Podrías echarle un vistazo a esto, stackoverflow.com/questions/26572115/… ? ¡Gracias!
S1U
@ s1u Hay un error en Xcode 6.1. Compruebe esta respuesta: stackoverflow.com/a/26641497/1085556
Bart van Kuik
@ s1u: Un par de cosas: (1) Puede haber varios idiomas preferidos; no existe un único "idioma actual", y (2) con respecto a su respuesta (eliminada), que devuelve el idioma dominante de la configuración regional actual (también conocida como región), no los idiomas preferidos del usuario.
Peter Hosey
2
La AppleLanguagesclave no está documentado, que es la única manera de conseguir documentado idiomas preferidos del usuario en los sistemas anteriores a OS X 10.5 (que, en estos días es muy raro, pero aún así, que está documentado ).
dreamlax
58

[NSLocale currentLocale]se basa en la configuración del formato de región del dispositivo, no en el idioma. Si la región está configurada en Estados Unidos, obtendrá en_US independientemente del idioma que esté usando.

Darren
fuente
Gracias Darren, eso me ayudó a comenzar, también descubrí cómo obtener la configuración de idioma actual, que es lo que realmente estaba tratando de hacer.
prairiedogg
2
Hola Prairiedogg, ¿cómo obtuviste la configuración de idioma actual? También tengo el mismo problema ... todos devuelven el valor EN para el idioma.
Zaldy
@ZaldzBugz: algo como: NSLocale * locale = [NSLocale currentLocale]; NSString * lang = [locale displayNameForKey: NSLocaleIdentifier valor: [[NSLocale favoriteLanguages] objectAtIndex: 0]];
powerj1984
3
este no es el caso en iOS 8. iOS 8 devolverá "de_US" si su idioma es alemán y su región es EE.UU. que es lo que se supone que debe hacer.
odyth
¿La región se actualiza automáticamente cuando el usuario, por ejemplo, va a Australia?
Nagendra Rao
9

Para nosotros, el problema era que estábamos anulando el idioma y la región de la aplicación en nuestro esquema de desarrollo. Asegúrese de que el Idioma de la aplicación esté configurado como Idioma del sistema en las opciones del esquema (Editar esquema -> Opciones).

Simon Bengtsson
fuente
Gracias Simon por señalar este aspecto ... Para las pruebas lo había configurado en el idioma local y olvidé cambiarlo después.
Ameer
¡Eso fue todo! No puedo creer que fuera una configuración de Xcode lo que lo estropeó.
Pedro
¡Esto salvó mi tocino! Gracias.
Kirby Todd
4

para mi ambos

NSString *localeString = [[NSLocale currentLocale] localeIdentifier];

y

NSArray *array = [NSLocale preferredLanguages];
self.label.text = array[0];

produce el mismo resultado cuando está en un simulador.

AlexW
fuente
2
De hecho, en mi caso, en iOS 8 / Xcode 6 siempre en_US
Adrian
3

Tuve un problema en el que el formato de los nombres de los meses aparecía en inglés en un dispositivo configurado en francés.

Mi solución fue usar esto:

    NSLocale *locale = [NSLocale localeWithLocaleIdentifier:[[NSLocale preferredLanguages] objectAtIndex:0] ];
    [self.monthNameFormatter setLocale:locale];
    [self.monthNameFormatter setDateFormat:@"MMMM"];
    [self.monthNameFormatter stringFromDate:myDate];
Ben Clayton
fuente
Descubrí que [NSLocale currentLocale] traducía correctamente los nombres de los meses al francés en iOS10, pero no en iOS11. Usando: NSLocale * locale = [NSLocale localeWithLocaleIdentifier: [[NSLocale favoriteLanguages] objectAtIndex: 0]]; solucionó el problema. Gracias Ben +1
hombre pájaro
2

Descubrí que si dejo "en_US" fuera, pero tengo una localización "en" que es una copia de "en_US", el simulador automáticamente comienza a respetar la configuración del idioma, pero tan pronto como "en_US" es una opción, siempre la elige independientemente de los ajustes.

Pantalones
fuente
1

La pregunta es demasiado antigua, pero este código puede ayudar a muchos:

El main.m debería verse así:

    NSString *localecode=[[NSLocale currentLocale] localeIdentifier];
    localecode=[localecode substringToIndex:2]; //en_GB -> en
    NSArray *arr = [NSLocale preferredLanguages];
    NSMutableArray * mutable = [arr mutableCopy];
    NSString *prefered = [mutable firstObject];
    if(![localecode isEqualToString:prefered]){
        if(![prefered isEqualToString:@"es"] && ![prefered isEqualToString:@"en"] && ![prefered isEqualToString:@"pt"]){
            int index = [mutable indexOfObject:@"en"];
            [mutable replaceObjectAtIndex:0 withObject:@"en"];
            [mutable replaceObjectAtIndex:index withObject:prefered];
            [[NSUserDefaults standardUserDefaults] setObject:mutable forKey:@"AppleLanguages"];

        }
        else{
            int index = [mutable indexOfObject:localecode];
            [mutable replaceObjectAtIndex:0 withObject:localecode];
            [mutable replaceObjectAtIndex:index withObject:prefered];
            [[NSUserDefaults standardUserDefaults] setObject:mutable forKey:@"AppleLanguages"];
        }
    }
    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));

¿Qué hace esto? Si el idioma actual del dispositivo es español, inglés o portugués, la aplicación usa las cadenas localizadas, por otro lado, si el idioma actual no es uno de esos y no es compatible con la aplicación, se establece en inglés.

cdiazmo
fuente
0

Muestra la configuración regional correcta cuando está en un iPad real. Sin embargo, el simulador tiene su propio iOS, que por defecto está configurado en en-US. Vaya a las preferencias de iOS del simulador y cambie el idioma y la región al que desee.

Eso hace el truco.

Ronald Hofmann
fuente