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
Моля, вижте моите редакции под „Групиране“. Използването на пакет ще раздели локализациите - person Olaf; 06.10.2012

Мисля, че пакет (както предлага Олаф) би работил чудесно, но друг начин с по-малко разходи, за да се гарантира, че вашите ресурси за локализиран низ не пречат на друг проект в същото решение (причиняване на странен проблем на хората, които използват повторно вашия компонент в друг локализиран проект) е да промените името на вашия localizable.strings файл на уникално име на файл. Това означава, че там, където сте използвали NSLocalizedString, сега трябва да използвате неговия вариант NSLocalizedStringFromTable (документация на Apple), където tableName е същото име като вашия файл с низове (без разширението .strings). Можете да дефинирате свой собствен макрос, така че това да е просто права замяна на NSLocalizedString с, да речем, FDTakeLocalizedString.

Сблъсък на имена на файлове е много по-малко вероятно да се случи с XIBs файлове или сторибордове, отколкото за файла 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