NSLocale currentLocale всегда возвращает «en_US», а не текущий язык пользователя

82

Я нахожусь в процессе интернационализации приложения для iPhone - мне нужно внести программные изменения в определенные представления в зависимости от текущего языкового стандарта пользователя. Я схожу с ума, потому что независимо от языковых предпочтений симулятора iPhone или реального оборудования, localeвсегда оценивается как «en_US»:

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

Самое безумное, что остальная часть приложения ведет себя так, как ожидалось. Правильные строки выбираются из файла Localization.strings и используются в интерфейсе, а также используются правильные файлы .xib для выбранной локали.

Я также пробовал следующее, но безрезультатно и с тем же результатом:

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

Что-то простое, что мне не хватает? Возможно, предпочтение или импорт?

Что раньше делал:

Как следует из ответа Даррена, предпочтение, которое я ищу, отсутствует NSLocale, скорее оно здесь:

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

Ответ Питера кажется лучшим решением:

NSArray* preferredLanguages = [NSLocale preferredLanguages];
NSLog(@"preferredLanguages: %@", preferredLanguages);
прерия
источник

Ответы:

36

Вместо того, чтобы напрямую запрашивать значения по умолчанию с использованием недокументированного ключа, запросите у класса NSLocale массив предпочтительных языков .

Питер Хози
источник
@PeterHosey У меня тоже есть аналогичная проблема с текущим языком, и я пробовал все, но ни один из них не работал. Так грустно ... Не могли бы вы взглянуть на это, stackoverflow.com/questions/26572115/… ? Благодаря!
S1U
@ s1u В Xcode 6.1 есть ошибка. Отметьте этот ответ: stackoverflow.com/a/26641497/1085556
Барт ван Куик,
@ s1u: Пара вещей: (1) Может быть несколько предпочтительных языков; не существует единого «текущего языка» и (2) в отношении вашего (удаленного) ответа, который возвращает доминирующий язык текущего языкового стандарта (также известного как регион), а не предпочтительные языки пользователя.
Питер Хози
2
AppleLanguagesКлюч не документированы, это единственный документированный способ получить предпочтительные языки пользователя на системах до OS X 10.5 (который, в эти дни очень редко, но все же, это будет документально ).
dreamlax
58

[NSLocale currentLocale]основан на настройках формата региона устройства, а не на языке. Если выбран регион США, вы получите en_US независимо от того, какой язык вы используете.

Даррен
источник
Спасибо, Даррен, это помогло мне начать, я также понял, как получить текущую языковую настройку, что я действительно пытался сделать.
prairiedogg
2
Привет, Prairiedogg, как вы получили текущую языковую настройку? у меня такая же проблема .. все возвращает значение EN для языка.
Zaldy
@ZaldzBugz: что-то вроде: NSLocale * locale = [NSLocale currentLocale]; NSString * lang = [язык displayNameForKey: NSLocaleIdentifier value: [[NSLocale preferredLanguages] objectAtIndex: 0]];
powerj1984
3
это не относится к iOS 8. iOS 8 вернет «de_US», если ваш язык немецкий, а ваш регион - США. что и должно было делать.
odyth
Обновляется ли регион автоматически, когда пользователь, скажем, едет в Австралию?
Нагендра Рао
9

Для нас проблема заключалась в том, что мы переопределяли язык приложения и область приложения в нашей схеме разработки. Убедитесь, что язык приложения установлен на системный язык в параметрах схемы (Изменить схему -> Параметры).

Саймон Бенгтссон
источник
Спасибо, Саймон, за указание на этот аспект ... Для тестирования я установил местный язык и потом забыл изменить его.
Ameer
Это было! Не могу поверить, что это была настройка Xcode, которая все испортила.
Педро
Это спасло мой бекон! Благодарю.
Кирби Тодд,
4

для меня оба

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

и

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

дают тот же результат, когда вы находитесь в симуляторе.

AlexW
источник
2
В самом деле, в моем случае на iOS 8 / Xcode 6 всегда en_US
Адриан
3

У меня возникла проблема, из-за которой названия месяцев форматирования отображались на английском языке на устройстве, настроенном на французский язык.

Мое решение было использовать это:

    NSLocale *locale = [NSLocale localeWithLocaleIdentifier:[[NSLocale preferredLanguages] objectAtIndex:0] ];
    [self.monthNameFormatter setLocale:locale];
    [self.monthNameFormatter setDateFormat:@"MMMM"];
    [self.monthNameFormatter stringFromDate:myDate];
Бен Клейтон
источник
Я обнаружил, что [NSLocale currentLocale] правильно переводил названия месяцев на французский в iOS10, но не в iOS11. Использование: NSLocale * locale = [NSLocale localeWithLocaleIdentifier: [[NSLocale предпочтительные языки] objectAtIndex: 0]]; исправил проблему. Спасибо, Бен +1
Birdman
2

Я обнаружил, что если я оставлю "en_US", но имею локализацию "en", которая является копией "en_US", симулятор автоматически начинает соблюдать языковые настройки, но как только "en_US" является вариантом, он всегда выбирает его независимо от настроек.

Штаны
источник
1

Вопрос слишком старый, но этот код может многим помочь:

Main.m должен выглядеть так:

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

Что делать? Если текущий язык устройства, например, испанский, английский или португальский, использует приложение, использующее локализованные строки, с другой стороны, если текущий язык не является одним из этих и не поддерживается приложением, установлен английский.

cdiazmo
источник
0

На реальном iPad он показывает правильную локаль. Однако у симулятора есть собственная iOS, которая по умолчанию установлена ​​на en-US. Перейдите в настройки симулятора iOS и переключите язык и регион на тот, который вам нужен.

Это трюк.

Рональд Хофманн
источник