NSLocale currentLocale zawsze zwraca „en_US”, a nie bieżący język użytkownika

82

Jestem w trakcie internacjonalizacji aplikacji na iPhone'a - muszę wprowadzić programowe zmiany w niektórych widokach w oparciu o aktualne ustawienia regionalne użytkownika. Oszalałem, ponieważ bez względu na preferencje językowe w symulatorze iPhone'a lub rzeczywisty sprzęt, localezawsze ocenia się jako „en_US”:

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

Szaleństwem jest to, że reszta aplikacji zachowuje się zgodnie z oczekiwaniami. Odpowiednie ciągi są wybierane z pliku Localization.strings i używane w interfejsie, a także używane są prawidłowe pliki .xib dla wybranej lokalizacji.

Próbowałem również następujących rzeczy, bezskutecznie iz takim samym wynikiem:

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

Czy brakuje mi czegoś prostego? Może preferencja czy może import?

Co robiłem:

Jak sugeruje odpowiedź Darrena, preferencji, której szukam, nie ma NSLocale, a raczej jest tutaj:

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

Odpowiedź Piotra wydaje się lepszym rozwiązaniem:

NSArray* preferredLanguages = [NSLocale preferredLanguages];
NSLog(@"preferredLanguages: %@", preferredLanguages);
prairiedogg
źródło

Odpowiedzi:

36

Zamiast sprawdzać wartości domyślne bezpośrednio przy użyciu nieudokumentowanego klucza, poproś klasę NSLocale o tablicę preferowanych języków .

Peter Hosey
źródło
@PeterHosey Mam podobny problem z aktualnym językiem i próbowałem wszystkiego, ale żaden z nich nie działał. Tak smutny ... Możesz na to spojrzeć, stackoverflow.com/questions/26572115/… ? Dzięki!
S1U
@ s1u Wystąpił błąd w Xcode 6.1. Sprawdź tę odpowiedź: stackoverflow.com/a/26641497/1085556
Bart van Kuik
@ s1u: Kilka rzeczy: (1) Może być wiele preferowanych języków; nie ma jednego „aktualnego języka” i (2) w odniesieniu do (usuniętej) odpowiedzi, która zwraca dominujący język aktualnej lokalizacji (czyli regionu), a nie preferowane języki użytkownika.
Peter Hosey
2
AppleLanguagesKlucz nie jest udokumentowany, to jedyny udokumentowany sposób, aby uzyskać użytkownika preferowane języki na systemy przed OS X 10.5 (co w dzisiejszych czasach jest bardzo rzadkie, ale nadal, to jest udokumentowane ).
dreamlax
58

[NSLocale currentLocale]jest oparty na ustawieniach formatu regionu urządzenia, a nie na języku. Jeśli region jest ustawiony na Stany Zjednoczone, otrzymasz en_US niezależnie od używanego języka.

Darren
źródło
Dzięki Darren, dzięki temu zacząłem. Zorientowałem się również, jak uzyskać aktualne ustawienia języka, co naprawdę próbowałem zrobić.
prairiedogg
2
Cześć Prairiedogg, skąd masz aktualne ustawienie języka? Mam również ten sam problem..all zwraca wartość EN dla języka.
Zaldy
@ZaldzBugz: coś takiego: NSLocale * locale = [NSLocale currentLocale]; NSString * lang = [locale displayNameForKey: NSLocaleIdentifier value: [[NSLocaleferredLanguages] objectAtIndex: 0]];
powerj1984
3
tak nie jest w iOS 8. iOS 8 zwróci „de_US”, jeśli Twoim językiem jest niemiecki, a Twoim regionem jest USA. co ma robić.
odyth
Czy region jest automatycznie aktualizowany, gdy użytkownik, powiedzmy, wyjeżdża do Australii?
Nagendra Rao
9

Dla nas problemem było to, że zastępowaliśmy język aplikacji i region aplikacji w naszym schemacie deweloperskim. Upewnij się, że język aplikacji jest ustawiony na język systemu w opcjach schematu (Edytuj schemat -> Opcje).

Simon Bengtsson
źródło
Dzięki Simon za zwrócenie uwagi na ten aspekt ... Do testów ustawiłem język na lokalny język i zapomniałem go później zmienić.
Ameer
To było to! Nie mogę uwierzyć, że to ustawienie Xcode to zepsuło.
Pedro
To uratowało mój bekon! Dzięki.
Kirby Todd
4

dla mnie obie

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

i

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

dają ten sam wynik, gdy jesteś w symulatorze.

AlexW
źródło
2
Rzeczywiście, w moim przypadku na iOS 8 / Xcode 6 zawsze en_US
Adrian
3

Wystąpił problem z formatowaniem nazw miesięcy w języku angielskim na urządzeniu z ustawieniem języka francuskiego.

Moim rozwiązaniem było użycie tego:

    NSLocale *locale = [NSLocale localeWithLocaleIdentifier:[[NSLocale preferredLanguages] objectAtIndex:0] ];
    [self.monthNameFormatter setLocale:locale];
    [self.monthNameFormatter setDateFormat:@"MMMM"];
    [self.monthNameFormatter stringFromDate:myDate];
Ben Clayton
źródło
Zauważyłem, że [NSLocale currentLocale] poprawnie tłumaczy nazwy miesięcy na francuski w iOS10, ale nie w iOS11. Używanie: NSLocale * locale = [NSLocale localeWithLocaleIdentifier: [[NSLocale preferowaneLanguages] objectAtIndex: 0]]; naprawiono problem. Dzięki Ben +1
birdman
2

stwierdziłem, że jeśli zostawię "en_US" poza lokalizacją "en", która jest kopią "en_US", symulator automatycznie zaczyna przestrzegać ustawień języka, ale gdy tylko "en_US" jest opcją, zawsze ją wybiera niezależnie ustawień.

Spodnie
źródło
1

Pytanie jest za stare, ale ten kod może pomóc wielu:

Plik main.m powinien wyglądać tak:

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

Co to robi? Jeśli aktualny język urządzenia to hiszpański, angielski lub portugalski, aplikacja używa zlokalizowanych ciągów znaków, z drugiej strony, jeśli bieżący język nie jest jednym z nich i nie jest obsługiwany przez aplikację, jest ustawiony na angielski.

cdiazmo
źródło
0

Pokazuje poprawne ustawienie regionalne na prawdziwym iPadzie. Jednak symulator ma własne iOS, które jest domyślnie ustawione na en-US. Przejdź do preferencji symulatora iOS i zmień język i region na żądany.

To załatwia sprawę.

Ronald Hofmann
źródło