Итак, нам очень захотелось перевести какое-нибудь приложение на родной великий и могучий. Как же это сделать? Давайте разбираться.

Во-первых, из чего состоит Cocoa-приложение. Как вам должно быть известно — файл с расширением .app — ничто иное, как обычная папка. В этой папке находится еще одна папка — Contents. Собственно нас именно она и будет интересовать. Итак, посмотрим, что же в ней находится:

  • MacOS — в этой папке хранится исполняемый файл приложения;
  • Resources — тут, как подсказывает название, лежат все «ресурсы» приложения (начиная от изображений и заканчивая файлами графического интерфейса);
  • Frameworks — тут лежат необходимые для работы приложения фреймворки;
  • + еще файл Info.plist (информация о пакете) и всякое другое;

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

На сегодняшний день разработчику приложений для Mac OS X не нужно ломать голову над тем, как ему добавить в свое творение поддержку второго (третьего или четвертого, не важно) языка. Система все сделает за него. Вот как примерно происходит процесс запуска типичного Cocoa-приложения:

1) при щелчке на some.app, Mac OS X ищет в нем папку MacOS (смешно, не правда ли? На самом деле не очень) и запускает лежащий в ней исполняемый файл

2) далее — система проверяет, какой язык установлен первым в списке языков системы. Для нас с вами это будет Ru (русский). Затем она идет в папку Resources и ищет в ней папку под названием ru.lproj (также она может называться Ru.lproj или Russian.lproj).

В этой папке (если все нормально и перевод заранее подготовлен) лежат файлы интерфейса (.nib/.xib) и файлы с расширением .strings (зачем они нужны — опишу чуть ниже). Mac OS X связывает файлы интерфейса из данной папки с запускаемым исполняемым файлом, и через некоторое время (когда все ресурсы загрузятся в оперативную память) мы увидим запущенное приложение с интерфейсом на родном языке.

К слову, если папки, соответствующей текущему системному языку, в приложении не оказалось — система автоматически повторит поиск, но уже для следующего за текущим языка из списка предпочитаемых. И так до тех пор, пока хоть какая-нибудь .lproj папка не будет найдена.

Теперь про .strings-файлы. В них хранятся пары «ключ-значение». По этому ключу программист из кода может получить локализованную строку для нужного ключа. Например, нужно в окно лога установщика выводить надпись «Здравствуй, пользователь!», причем, на родном для этого пользователя языке. Понятно, что эту строку нельзя записать в файл интерфейса приложения, потому что она генерируется динамически. Тогда разработчик просто берет и создает файл Localizable.strings (на самом деле, название может быть вобще любое), по одному для каждого языка (т.е. по одному в каждую .lproj папку приложения). И пишет в нем например, следующее: (пример для русской локализации)

А для английской локализации этот файл будет выглядеть вот так:

(заметьте, что ключ в обеих strings-файлах один и тот же — без этого никак).

После этого, разработчик может уже не задумываться над тем, на каком языке разговаривает пользователь — для того чтобы получить правильную версию строки он просто пишет:

Все очень просто. Поэтому .strings-файлы используются в большинстве Cocoa-приложений и мы очень часто будем с ними работать при переводе.

Есть пара моментов, на которые нельзя не обращать внимание при переводе .strings файлов. Дело вот в чем: помимо простых строк (как в примере выше), нам могут встретиться строки подобные этой:

(Никакой ошибки нет — в качестве ключа часто используются полные строки на родном для разработчика языке).

Тут надо обратить внимание на пару символов «%@» — это своего рода индикатор, на место которого будет вставлена какая-то другая строка во время выполнения программы (вместо символа «@» может быть «d», «f», «c» (да и не только они), в этом случае будут подставлены соответственно целое число, дробное число и одиночный символ). Разумеется, при переводе нельзя этот самый индикатор терять — мало того, что до пользователя может не дойти какая-то важная информация, так это еще может привести к аварийному завершению работы приложения.

Посмотрим на еще один пример (из реального приложения Coda):

Что это за странные индикаторы с цифрами? Все дело в том, что если переводить фразу на «человеческий» русский язык, то имя файла будет стоять на первом месте, а описание ошибки — на втором. В оригинале же — наоборот. Получается, что строка у нас получиться вида:

Дабы избежать таких ситуёвин для установки последовательности индикаторов используются обозначения типа %[email protected] (т.е на данном месте должен стоять индикатор, который в исходной строке-ключе стоял на втором месте). Разумеется, если все параметры в переведенной строке стоят на тех же местах, что и в исходной — никаких порядковых номеров указывать не нужно.

 

Локализайция файлов интерфейса

Итак, самая важная часть локализации — перевод файлов графического интерфейса. Они бывают нескольких видов:

1) xib-файлы. Это «сырые» файлы, в которых находится информация о том, где какой объект интерефейса находится, и какие у него есть свойства и параметры. Их генерирует специальная программа — Interface Builder (или просто IB), с помощью которой создается интерфейс для процентов 96-98 всех Cocoa-приложений (в оставшихся двух процентах проложений — весь интерфейс создается динамически, из кода во время запуска, но, к нашему счастью, они довольно редки). Грубо говоря, Mac OS X «не понимает» формат такого описания интерфейса — так что .xib файлы предназначены только для использования самим IB.

2) .nib — файлы. Они представляют собой «конвертированную» версию .xib-файлов, которая создается при компиляции (сборке) приложения. Именно они и предназначены для использования системой. В свою очередь, .nib’ы бывают двух видов:

2.1) «простые» — представляют собой bundle(т.е. папку, как например, файл приложения), в котором хранятся 2 файла: первый — уже знакомый нам .xib (только называется он designable.nib), а второй — скомпилированный .nib-файл (см. ниже) — keyedobjects.nib.

sharednibs

Редактировать такие «простые» bundle’ы можно прямо в IB.

2.2) скомпилированные или двоичные nib’ы. На этот раз это уже не bundle, а один единственный двоичный (aka бинарный) файл. Текстовыми редакторами не открывается, исключение составляет лишь BBEdit. Но это не проблема, так как мы спокойно можем этот файл конвертировать в обычный текстовый xml. Для этого выполним команду:

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

Однако даже после преобразования в простой xml, его нельзя будет открыть при помощи IB — т.е. все изменения можно будет вносить только «ручками», в текстовом редакторе.

Ну а так как .xib файлы имеют место быть только при разработке, то в готовых приложениях мы будем сталкиваться именно с .nib-файлами. Причем, в большинстве своем это будут именно бинарные .nib’ы (хотя, ничего не мешает вам написать вежливое письмо разработчику той или иной программы и попросить его прислать вам нескомпилированные файлы для перевода — как правило, редко кто отказывает — которые очень удобно и, что самое главное, быстро переводятся, используя IB).

Итак, вы выбрали приложение для перевода. Первым делом в папке Resources нужно создать каталог ru.lproj. В него копируете _все_ содержимое, например, папки English.lproj или любой другой .lproj, не важно. На этом приготовления заканчиваются и можно переступать непосредственно к локализации.

Алгоритм перевода примерно такой:

  • самым первым делом переводим файлы .strings. В некоторых приложениях они содержат абсолютно все нужные строки, так что перевод на этом шаге заканчивается (но, к сожалению, это бывает очень редко).

Тут стоит отметить, что система подгружает ресурсы приложения при его запуске, т.е. чтобы внесенные вами изменения вступили в силу, необходимо будет перезапустить приложение, если оно у вас запущено (а оно, кстати, у вас должно быть запущено во время перевода, чтобы видеть, где и как расположены те надписи, которые вы переводить в данный момент. Это также относится и ко вем последующим шагам);

  • как я уже писал выше, для начала бинарные nib’ы (рассматриваем именно их, потому как «простые» спокойно редактируются в IB — а там и так все понятно) нужно конвертировать в простой текст:

  • так как большинство строк, которые необходимо перевести начинаются с большой буквы, лего получить их список. Для этого воспользуемся стандартной утилитой grep:

После выполнения этой команды в файле по адресу /path/to/new/text/file будет находится список всех строк, начинающихся с большой буквы, за исключением служебных (которые, как понятно, переводить не нужно — любое их изменение чревато порчей nib-файла);

  • на данном этапе открываем оба файла (.nib + полученный на шаге 2) и по очереди ищем в .nib файле строки из списка. Как только нашли — заменяете текст между тегов <string> на нужный.

При всей кажущейся простоте данного процесса есть одно «но» — почти все переводимые вами строки станут длиннее, чем они были до этого. А это видет к тому, что надписи в самом приложении будут либо «обрезаться», либо наползать на другие элементы интерфейса. Нам, понятное дело, этого не хочется ни разу. Что же делать?

На самом деле, помимо банального изменения строк, в .nib файле мы можем изменить характеристики любого элемента (кнопки, надписи, окна и пр), а в частности — его размеры. Строка, отвечающая за размеры объекта находится выше (по тексту) его названия\надписи\etc (в общем, той строки, что мы с вами переводим), она так же заключена в теги <string>…</string> и имеет вид:

Формат строки следующий: { {x, y} , {длина (ширина), высота} }, где x и y — координаты объекта на той или иной форме.

Эти размеры можно изменять по своему вкусу так же как и строки. Следует всегда проверять любые внесенные вами изменения в программе — очень сложно сходу, «на глаз», определить, какие новые размеры нужно указать для того или иного элемента, чтобы он не портил внешнего вида приложения.

Вот собственно и все, что касается локализации приложений. Возможно вам покажется все это очень нудным и сложным, но на самом деле стоит перевести одно-два приложения, и все это уже делается на автомате.

Если после прочтения данного руководства у вас остались/возникли какие-товопросы — задавайте их в комментариях. Буду рад помочь.

© eric_bro (aka VioLet)

Seo wordpress plugin by www.seowizard.org.