Пользовательский NSLocalizedString? - PullRequest
3 голосов
/ 06 июля 2011

Можно ли использовать инфраструктуру NSLocalizedString (на основе localizable.strings) с определенной пользователем "локализацией"?

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

Ответы [ 6 ]

9 голосов
/ 09 мая 2012

Вот моя Пользовательская реализация, которая использует NSLocalizedString, которая использует комментарий в качестве значения по умолчанию:

(NSLocalizedStringWithDefaultValue не работает должным образом с genstring, поэтому я предложил это решение)

1. В предварительно скомпилированном заголовке (файл .pch) переопределите макрос «NSLocalizedString»:

// cutom NSLocalizedString that use macro comment as default value
#import "LocalizationHandlerUtil.h"

#undef NSLocalizedString
#define NSLocalizedString(key,_comment) [[LocalizationHandlerUtil singleton] localizedString:key  comment:_comment]

2. создать класс для реализации обработчика локализации

#import "LocalizationHandlerUtil.h"

@implementation LocalizationHandlerUtil

static LocalizationHandlerUtil * singleton = nil;

+ (LocalizationHandlerUtil *)singleton
{
    return singleton;
}

__attribute__((constructor))
static void staticInit_singleton()
{
    singleton = [[LocalizationHandlerUtil alloc] init];
}

- (NSString *)localizedString:(NSString *)key comment:(NSString *)comment
{
    // default localized string loading
    NSString * localizedString = [[NSBundle mainBundle] localizedStringForKey:key value:key table:nil];

    // if (value == key) and comment is not nil -> returns comment
    if([localizedString isEqualToString:key] && comment !=nil)
        return comment;

    return localizedString;
}

@end

3. Используйте это!

Убедитесь, что вы добавили скрипт Run в ваши фазы сборки приложения, чтобы ваш файл Localizable.strings обновлялся при каждой сборке, то есть новая локализованная строка добавлялась в ваш файл Localized.strings:

Моя фаза сборки Script - это сценарий оболочки:

Shell: /bin/sh
Shell script content: find . -name \*.m | xargs genstrings -o MyProjectFolder

Итак, когда вы добавляете эту новую строку в свой код:

self.title = NSLocalizedString(@"view_settings_title", @"Settings");

Затем выполните сборку, ваш файл ./Localizable.scripts будет содержать новую строку:

/* Settings */
"view_settings_title" = "view_settings_title";

И так как ключ == значение для 'view_settings_title', пользовательский LocalizedStringHandler будет возвращать комментарий, т.е. «Настройки»

Вуаля: -)

4 голосов
/ 06 июля 2011

NSLocalizedString - это просто макрос, определенный в NSBundle.h
Переопределите его или создайте новый, например NSGenderAwareLocalizedString, чтобы соответствовать вашим потребностям.

С новым макросом вы можете делать все, что угоднохочу: две строки файлов на язык, один для мужчин и один для женщин.Или вы можете определить соглашение для получения ключа для локализованной строки для женщины из ключа мужской локализованной строки.

2 голосов
/ 03 апреля 2013

Вот моя пользовательская реализация, которая использует NSLocalizedString, которая использует комментарий в качестве значения по умолчанию:

-> Здесь я конвертирую в 2 языка (английский и итальянский)

-> Поместить этот методв классе appdelegate

- (NSString*)languageSelectedStringForKey:(NSString*) key {        

    NSString *path = nil;
    NSString *language = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppLanguage"];

    if ([language isEqualToString:@"English"])
        path = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"];
    else if ([language isEqualToString:@"Italian"])
        path = [[NSBundle mainBundle] pathForResource:@"it" ofType:@"lproj"];

    NSBundle* languageBundle = [NSBundle bundleWithPath:path];
    NSString* str=[languageBundle localizedStringForKey:key value:@"" table:nil];
    return str;
}

-> вызвать этот метод с помощью

 self.title = [appDelgate languageSelectedStringForKey:@"Back"];

, который преобразует Back в выбранный язык.

2 голосов
/ 31 марта 2013

Для этого есть специальный механизм. Из справочника Apple: Поиск пользовательских функций с помощью genstrings

Инструмент genstrings ищет основной фонд и фундамент строковые макросы по умолчанию. Он использует информацию в этих макросах для создайте строковые записи в строковых файлах вашего проекта. Вы можете также направлять genstrings для поиска пользовательских функций загрузки строк в ваш код и использовать эти функции в дополнение к стандартным макросам. Вы можете использовать пользовательские функции для переноса встроенной загрузки строк подпрограммы и выполнить дополнительную обработку или вы можете заменить поведение обработки строк по умолчанию с вашей собственной пользовательской моделью.

Если вы хотите использовать genstrings со своими собственными пользовательскими функциями, ваш функции должны использовать соглашения об именах и форматировании, используемые Основы макросов. Параметры для ваших функций должны соответствовать параметры для соответствующих макросов точно. Когда вы вызываете genstrings, вы указываете опцию -s, за которой следует имя функция, которая соответствует макросу NSLocalizedString. Ваш другой имена функций должны затем строиться из этого базового имени. Например, если Вы указали имя функции MyStringFunction, другая ваша функция имена должны быть MyStringFunctionFromTable, MyStringFunctionFromTableInBundle и MyStringFunctionWithDefaultValue. Инструмент genstrings ищет эти функции и использует их для создания соответствующих файлов строк.

Для реализации собственного поведения используйте NSBundle метод localizedStringForKey:value:table:

0 голосов
/ 30 мая 2019

В течение пары лет Xcode имеет LOCALIZED_STRING_MACRO_NAMES, так что вы можете поместить свои собственные NSLocalizedString альтернативные имена макросов, если они следуют той же структуре параметров, и Xcode корректно экспортирует / импортирует их, подобно genstrings answer

0 голосов
/ 13 июня 2014

@ Guillaume предоставляет лучшее решение, фактически не показывая реализацию.Поскольку автору вопроса не удалось это выяснить, я решил включить его для будущих людей.Я нашел ветку полезной, теперь она более чем полезна.:)

Как уже упоминалось @Guillaume, лучшим решением является создание собственного макроса с поиском в таблице.«Таблица» - это просто имя другого файла, который содержит варианты.В этом случае я предполагаю, что вы назовете свой файл «Female.strings»

. Это обеспечивает максимальную гибкость и дает вам решение, которое не требует определения записей для ОБА случаев.Это действительно очень полезно для вашего случая, так как не все фразы могут иметь женские формы.

В результате, следующее решение не требует повторяющихся записей, что довольно круто!

Первое определениеВаш макрос:

#define SXLocalizedString(key, comment) [Utility SXLocalizedString:key with:comment]

Затем определите расширенную функцию следующим образом:

+ (NSString*)SXLocalizedString:(NSString*)str with:(NSString*)comment {
    NSString* feminine = NSLocalizedStringFromTable(str, @"Female", comment);
    NSString* value = NSLocalizedString(str, comment);
    if ([self userIsFemale] &&
        feminine) {
        // choose the feminine version of the string
        value = feminine;
    }
    return value;
}
...