Локализация приложения для iPhone - проблемы с английским?

У меня есть приложение, которое я перевожу на несколько языков. Проблема в том, что приложение будет иметь несколько других значений в Австралии, чем в Новой Зеландии, которые являются англоязычными странами.

Я создал языковые файлы en_AU и en_NZ, но они оба используют стандартный английский файл. Я удалил англоязычный файл, но это продолжает происходить ...

Любые идеи о том, как я могу заставить это работать?

Спасибо,

--d


person dewberry    schedule 22.07.2010    source источник


Ответы (5)


При локализации iPhone (или это локализация?) не учитывается регион, установленный пользователем (например, Великобритания, Австралия, Новая Зеландия). По умолчанию доступен только один «английский» перевод. Однако вы можете взломать вещи, чтобы заставить его использовать другую настройку перевода - я только что сделал это для выбора между «английским» (США) и «en_GB» (британский английский).

В вашем файле main.m измените его так, чтобы он выглядел примерно так, как показано ниже (добавьте свои собственные тесты для Новой Зеландии или Австралии)

int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

// Set up the locale jiggery pokery
NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];
NSString *locale = [[NSLocale currentLocale] objectForKey: NSLocaleCountryCode];
if ([language isEqualToString:@"en"] && [locale isEqualToString:@"GB"]) {
    [[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"en_GB", @"en", nil] forKey:@"AppleLanguages"];
}

int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;

}

Это выталкивает язык пользователя (например, «en») в язык NSString, а языковой стандарт пользователя (например, NZ, GB, AU) - в языковой стандарт NSString. Если они (в моем случае) совпадают с en и GB, тогда я устанавливаю настройки языка по умолчанию для пользователей как «en_GB», а затем «en».

Затем в вашем приложении делегируется метод application: didFinishLaunchingWithOptions, который вы хотите удалить этот параметр NSUserDefaults, который вы только что установили с помощью кода

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

На этом этапе можно безопасно удалить, потому что вся инициализация пакета завершена. Теперь ваше приложение должно использовать файл Localization.strings в каталоге en_GB.lproj.

Это немного ужасное хакерское решение, но оно работает для меня.

person rickerbh    schedule 22.07.2010

Я придумал, как мне кажется, немного улучшенную версию принятого ответа Рикербха. Первое, что нужно понять, это то, что пользовательские настройки по умолчанию организованы в домены, а ключ @"AppleLanguages" поступает не из домена приложения, а из некоторого домена, расположенного выше по иерархии доменов. Это означает, что полностью безопасно удалить его из пользовательских настроек по умолчанию:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:@"AppleLanguages"];

После вызова этого кода вы заметите, что вызов [defaults objectForKey:@"AppleLanguages"] по-прежнему возвращает значение. Поэтому вместо того, чтобы удалять @"AppleLanguages" в какой-то момент позже, что может быть проблематичным в зависимости от сложности вашего приложения, вы хотите сделать обратное: удалить @"AppleLanguages" немедленно. По сути, это сбрасывает его обратно до значения по умолчанию и фиксирует любые изменения, внесенные системой, если, например, пользователь изменил свой предпочтительный язык.

Вот что я делаю:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:@"AppleLanguages"];

NSMutableArray *appleLanguages = [[defaults objectForKey:@"AppleLanguages"] mutableCopy];
NSString *region = [[NSLocale currentLocale] objectForKey:NSLocaleCountryCode];
NSArray *languages = [appleLanguages filteredArrayUsingPredicateFormat:@"not (self contains '-')"];
for (NSString *language in languages) {
    NSString *languageAndRegion = [NSString stringWithFormat:@"%@-%@", language, region];
    [appleLanguages removeObject:languageAndRegion];
}
for (NSString *language in languages) {
    NSString *languageAndRegion = [NSString stringWithFormat:@"%@-%@", language, region];
    NSInteger index = [appleLanguages indexOfObject:language];
    [appleLanguages insertObject:languageAndRegion atIndex:index];
}
[defaults setObject:appleLanguages forKey:@"AppleLanguages"];

(Обратите внимание, что filteredArrayUsingPredicateFormat: - это метод расширения, который я написал. Это не ракетостроение, чтобы выяснить, что он делает или как работает.)

Это создает локализацию для каждого языка в списке в сочетании с регионом пользователя. Например, если исходный список был es en en-GB, а регион пользователя - AU, мы получим es-AU es en-AU en en-GB. Обратите внимание, что es-AU не существует, но это не имеет значения. Поскольку приложение не находит связанных локализаций или ресурсов, оно просто игнорирует их.

person Gregory Higley    schedule 16.01.2013
comment
В ios 8.1 это решение. - person Mike; 25.10.2014
comment
Это выглядит солидно. Следует добавить, что @selector (filterArrayUsingPredicateFormat :) - это метод категории в NSArray, который вы можете найти здесь: github.com/huguesbr/library-ios/blob/master/Categories/ - person Brian Sachetta; 11.03.2015
comment
Кроме того, где вы помещаете это в свой код: в делегат приложения или в свою основную функцию? - person Brian Sachetta; 11.03.2015
comment
Ставлю в main. Конечно, это не вариант для проектов Swift, поэтому я не знаю, как подойти к нему там. Никогда не пробовал в делегате приложения. Там все может нормально работать. Точно сказать не могу. - person Gregory Higley; 11.03.2015
comment
Похоже, что это также работает на iOS 9, но это шутка, что мы должны это делать. - person Ricky; 16.09.2015


У меня были те же проблемы с немецким языком, и я думаю, что нашел «правильное» решение. Ошибка заключалась в том, что изначально моим базовым языком был только «немецкий (de)», при добавлении локализаций «немецкий / австрийский (de_AT)» файлы игнорировались. При изменении основного языка на «Немецкий / Германия (de_DE)» австрийские переводы не игнорировались.

person tomk    schedule 26.03.2013

Здесь стоит отметить, что XCode вводит в заблуждение - вы можете перейти в Project (не Target), Info, Localizations, нажать кнопку +, которая появляется под списком языков, а затем прокрутить вниз до конца списка языков, которые появляются в всплывающее окно, пока вы не дойдете до «Другое» (со стрелкой вправо рядом), откроется красивый большой список, который включает региональные варианты для языков. Однако эти региональные варианты не работают на iPhone - вы ничего не получаете (как задокументировано Apple и упоминается в другом ответе, который появляется здесь). Очевидно, необходимо одно из перечисленных выше решений на основе кода.

person Andy Weinstein    schedule 25.08.2014