iOS как локализовать файлы для модуля

У меня есть класс, который реализует функцию «Сделать фото/Выбрать из библиотеки», которую мы все знаем и любим. Это здесь https://github.com/fulldecent/FDTake Это включено в другие мои проекты через git подмодуль, и это работает нормально.

Теперь мне нужно перевести текст в этом классе на китайский, чтобы он был «拍照 / 选照片» или что-то в этом роде. Есть ли хороший способ разместить там переводы, чтобы каждый мог их использовать?


person William Entriken    schedule 05.10.2012    source источник


Ответы (2)


Локализация обычно выполняется макросом NSLocalizedString(<#key#>, <#comment#>). В источнике вы замените всю жестко закодированную строку макросом. Например:

    [self.buttonTitles addObject:@"Hi"]; // hard coded greeting

с участием

    [self.theLabel setText:(NSLocalizedString(@"theKey", @"Hi"))];

Затем genstrings (изнутри терминала) используется для сканирования файла реализации (*.m) и записи его вывода в папку языкового проекта (здесь: en.lproj)

    $ genstrings -o en.lproj/ *.m

В каталоге en.lproj/ файл с именем Localizable.strings. Его содержимое будет:

/* Hi */
"theKey" = "theKey";

Комментарий /* Hi */ взят из нашего исходного кода. Строка Hi должна отображаться для (англоязычного) пользователя. Итак, нам нужно отредактировать строку справа от знака равенства и сделать ее приветствием, = "theKey" должно стать = "Hi":

/* Hi */
"theKey" = "Hi!";

Все идет нормально

Все это хорошо, если строк всего несколько или когда нет намерения когда-либо изменять строки. В тот момент, когда gestrings запустится снова, изменения будут перезаписаны, и вы фактически потеряете работу, проделанную в Localizable.strings. Идея может заключаться в том, чтобы записать вывод genstrings в другое место. Но тогда вам придется вручную объединять изменения. Как только файл Localizable.strings разрастается, попытки синхронизировать исходный код и Localizable.strings становятся кошмаром. Так давайте попробуем этого избежать.

Большая помощь приходит от использования NSLocalizedStringWithDefaultValue(<#key#>, <#tbl#>, <#bundle#>, <#val#>, <#comment#>). Этот макрос позволит установить значение по умолчанию в файле Localizable.strings и, кроме того, избавит от необходимости первоначального редактирования поля значения.

Собираем вместе:

[self.theLabel setText:NSLocalizedStringWithDefaultValue(@"theKey2", @"Localizable", [NSBundle mainBundle], @"Hi!", @"informal greeting"))];

После запуска команды genstrings, которая использовалась выше, в Localizable.strings появилось небольшое изменение.

/* informal greeting */
"theKey2" = "Hi!";

Помимо комментария, который теперь сообщает переводчику, что мы хотим неформальное приветствие, “Hi!” уже присутствует в поле значения. Нет необходимости заходить в файл Localizable.strings, искать нужную строку, изменять форму поля «theKey» на «Hi!». genstrings сделал это за нас на основе значения по умолчанию, предоставленного с NSLocalizedStringWithDefaultValue.

Добавьте файл Localizable.strings в проект xcode.

Выполнение переводов

После изменения исходного кода для нового языка изнутри Xcode сначала добавьте локализацию в Localizable.strings. Xcode сгенерирует копию Localizable.strings в подпапке на основе исходного Localizable.strings.

Лично я говорю не по-китайски, а по-немецки. Так что, если добавить немецкую локализацию, мой перевод будет под de.lproj/Localizable.strings, итальянский под it.lproj/ и так далее.

Отредактируйте новый Localizable.strings по мере необходимости:

(Немецкий)

/* informal greeting */
"theKey2" = "Hallo!";

(итальянский)

/* informal greeting */
"theKey2" = "Ciao!";

а затем построить и запустить.

********* begin edit

Собери это

Выше рассматривается «стандартный» проект xcode. Вы спрашиваете о создании модуля, что позволяет вашему коду стать дополнением к проекту. Я предлагаю вам создать бандл с локализациями. Когда кто-то включит ваш код в свой проект, локализации останутся отдельными. Полная документация по пакетам: здесь.

Проект, который использует пакеты для локализации, называется QuincyKit (вероятно, их больше, этот был первым, который пришел на ум)

Поэтому при размещении локализации в пакете, отличном от mainBundle, [NSBundle mainBundle] в строке ниже должно измениться.

    [self.theLabel setText:NSLocalizedStringWithDefaultValue(@"theKey2", @"Localizable", [NSBundle mainBundle], @"Hi!", @"informal greeting"))];

Вместо получения строк из mainBundle получите ссылку на свой собственный модуль. Документы предлагают:

    NSBundle* myBundle = [NSBundle bundleForClass:[self class]];

Таким образом, строка становится:

    [self.theLabel setText:NSLocalizedStringWithDefaultValue(@"theKey2", @"Localizable", myBundle, @"Hi!", @"informal greeting"))];

********* end edit


PS: : мой исходный текст может можно увидеть здесь

person Olaf    schedule 06.10.2012
comment
Спасибо, и на всякий случай, когда я буду распространять это как модуль, я буду распространять файлы FDTakeController.h, FDTakeController.m и все папки lproj, верно? Они могут включить мои папки lproj, а затем использовать другие lproj для остальных ресурсов своего проекта? - person William Entriken; 06.10.2012
comment
Пожалуйста, смотрите мои правки в разделе Bundle it up. Использование пакета разделит локализации - person Olaf; 06.10.2012

Я думаю, что пакет (как предлагает Олаф) отлично сработает, но это другой способ с меньшими накладными расходами, чтобы ваши локализуемые строковые ресурсы не мешали другому проекту в том же решении (создание странной проблемы для людей, повторно использующих ваш компонент в другом локализованном проекте), заключается в изменении вашего localizable.strings имени файла на уникальное имя файла. Это означает, что там, где вы использовали NSLocalizedString, теперь вам нужно использовать его вариант NSLocalizedStringFromTable (Документация Apple), где tableName — это то же имя, что и у файла строк (без расширения .strings). Вы можете определить свой собственный макрос, так что это будет просто прямая замена NSLocalizedString, скажем, FDTakeLocalizedString.

Конфликт имен файлов с файлами XIB или раскадровками возникает гораздо реже, чем с файлом localizable.strings. Но в обоих случаях, если вы используете соглашение об именах с префиксом (скажем, FDTake.strings и FDTake-Main.xib), это устранит риск и может только помочь.

person Clafou    schedule 09.10.2012
comment
Просто пытаюсь понять рабочий процесс. Так что я бы поставил FDTake.m, FDTake.h, FDTake.strings, а затем кучу папок lproj: en.lproj/FDTake.strings, fr.lproj/FDTake.strings. Затем для пользователей они перетаскивали M и H в свой проект. А потом они перетаскивают стринг-файлы в каждую из своих папок lproj, или они перетаскивают мои папки прямо в свой проект? - person William Entriken; 11.10.2012
comment
Второй вариант (перетащите папки прямо внутрь или, фактически, только в родительскую папку ваших подпапок) будет работать нормально. XCode все равно — у вас может быть несколько папок lproj для одного и того же языка, но, в конце концов, в пакете приложений, созданном XCode, все они попадут в один lproj в корневой папке. - person Clafou; 12.10.2012