Локализация приложений в Mac OS

На просторах блогосферы я нашёл интереснейшую статью о локализации приложений для iPhone / iPod Touch. Поскольку Ordo Dei считает, автор оригинальной записи давно не появлялся в блоге, я тоже решил сохранить запись целиком.

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

Локализация, применительно к разрабатываемым для Mac OS приложениям, должна включать в себя одну или несколько следующих частей:

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

    Правильно проведенный процесс интернационализации значительно снижает объем работы по дальнейшей локализации приложения и добавление дополнительных поддерживаемых языков в программу.

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

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

    Calculator.app/                      сборка (bundle)
        Contents/
            MacOS/
                Calculator               исполняемый файл
            Info.plist
            Resources/                   папка с ресурсами
                Calculator.icns
                tapeButton.tif           не локализованные ресурсы
                English.lproj/           папка с ресурсами, локализованными для англоязычной аудитории
                    Localizable.strings  динамически отображаемые строки
                    Calculator.nib       интерфейс приложения
                    CalculatorHelp/      файлы документации и помощи
                ru.lproj/                папка с ресурсами, локализованными для русскоязычной аудитории
                    Localizable.strings
                    Calculator.nib
                    CalculatorHelp/ ...

    Процесс создания папок lproj и версий ресурсов для каждой из них лежит на плечах XCode, а вот ответственность за перевод и локализацию — на ваших.

    Интернационализацию или подготовку приложения к дальнейшей локализации можно условно разделить на два этапа:

    1. Модификация кода приложения и использование консольной утилиты genstrings для формирования файла, содержащего все строки, используемые в коде приложения, которые требуют перевода
    2. Создание затребованного количества папок lproj под локализацию и модификация ресурсов в них для указанных языков

    Начнем с первого этапа и воспользуемся созданным нами в прошлых постах приложением txtEdit в качестве основы для наших экспериментов.

    Чтобы показать все возможные варианты локализации нам потребуется внести в код проекта некоторые изменения. Во-первых, удалите из класса mainViewController метод awakeFromNib, в котором мы формировали подпись “Back” к кнопке возврата. Прелесть создания приложений в XCode (как, собственно, и в любом языке) заключается в том, что к одному и тому же результату можно прийти несколькими путями. Дело в том, что свойство backBarButtonItem доступно для изменения не только программным путем, но и в Interface Builder.

    Откройте файл MainWindow.xib и, раскрыв все дерево подчинения элементов, выберите в нем Navigation Item, принадлежащий mainViewController.

    iphone_1

    В инспекторе свойств перейдите на закладку атрибуты и установите значение поля Back Button как “Back”.

    iphone_2

    Благодаря нашим стараниям, в интерфейсе приложения появится новый элемент BarButtonItem, отождествленный с нашей кнопкой возврата.

    iphone_3

    Для каждой версии перевода мы впишем новое значение подписи к кнопке. Сохраните и закройте файл MainWindow.xib.

    Для создания файла переводов для строк, используемых в коде приложения, нам, прежде всего, необходимо подготовить сам код к локализации, ведь в более общей ситуации нам нет нужны переводить все используемые в приложении строки и фразы. Чтобы показать, что для данного текста будет браться его локализованный вариант согласно текущей языковой настройки пользователя, необходимо конвертировать строку в вызов метода NSLocalizedString. Для примера, сделаем перевод кнопки “Done”, которую мы использовали в классе txtEditViewController.

    Вы помните, что мы создавали кнопку вручную, используя метод initWithBarButtonSystemItem:target:action:, где в качестве параметров не указывается подпись к кнопке. Поэтому нам потребуется заменить строку инициализации на следующую:

    UIBarButtonItem *buttonDone = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"Done", @"")                                                                style:UIBarButtonItemStyleDone                                                               target:self                                                               action:@selector(doneAction:)];  

    Во-первых, мы использовали конструктор кнопки с указанием подписи к ней, а во-вторых, добавили вызов NSLocalizedString, тем самым указав на выборку переведенной версии строки “Done”. В реальности NSLocalizedString является не методом, а макросом, скрывающим следующий вызов:

    [[NSBundle mainBundle] localizedStringForKey:@"Done" value:@"" table:nil];  

    Для обращения к ресурсам приложения используются метода класса NSBundle. localizedStringForKey:value:table возвращает перевод указанной строки. В случае, если значения перевода не существует, используется значение value. Параметр table указывает на название файла перевода. По умолчанию, это Localizable.strings.

    Нам осталось только сформировать данный файл. Для этого запустите терминал и перейдите в папку Classes нашего приложения. Находясь в этой папке, запустите команду:

    genstrings ./*.m  

    Результатом выполнения команды станет сформированный в том же каталоге файл перевода для всех используемых в приложении классов. Добавьте файл Localizable.strings в проект, обязательно указав при его импортировании кодировку UTF-16.

    iphone_4

    Файл перевода представляет собой обычный текстовый файл, содержащий пары ключ-значение. Ключ может быть строкой символов только из нижней части ASCII-таблицы, то есть преимущественно состоящим из латинских букв, цифр и специальных символов. В качестве ключа могут использоваться также и сложные выражения, строки с информацией о форматировании, не нарушающие данного условия.

    "File %@ not found." = "Le fichier %@ n’existe pas.";  

    Локализация приложений

    Процесс локализации приложений в Mac OS легок и прост. Исполняемый файл программы отделен от локализованных ресурсов (текстов, изображений, звуков), сгруппированных по отдельным папкам. Как вы видели выше, локализованные ресурсы хранятся в отдельной .lproj директории для каждого поддерживаемого языка. Папки .lproj названы согласно спецификациям ISO. Содержимое всех таких папок должно быть одинаковым.

    В региональных настройках Mac OS вы указываете свой основной язык и список дополнительных языков. В случае, если приложение не поддерживает ваш основной язык, то будет использоваться язык из указанного списка. Если ни для одного из указанных языков не было найдено файлов перевода, то приложение будет использовать язык, указанный по умолчанию при разработке программы. Это значение указывается в переменной “Localization native development region” (эквивалент в xml-варианте — CFBundleDevelopmentRegion) в файле Info.plist.

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

    В своих программах вы можете использовать обобщения для представления единых данных для ряда регионов. Например, создание пакета ресурсов en.lproj, единого для США, Великобритании и Австралии вместо отдельных en_US.lproj, en_GB.lproj, и en_AU.lproj, позволит вам уменьшить размер вашей сборки. В качестве имени для папки с локализованными версиями ресурсов можно использовать полное название языка, например, Russian, German, Japanese, но поддержка такого наименования может быть убрана из будущих версий Mac OS и лучше придерживаться принятых в ISO обозначений.

    Как я говорил выше, XCode берет на себя работу по созданию lproj директорий, и пришло время показать как он это делает. В нашем приложении мы будем локализовать два файла: MainWindow.xib и Localizable.strings. Найдите их в списке файлов в проекте XCode и последовательно для каждого выполните следующие действия.

    Нажмите правой кнопкой мыши на файл и выберите пункт Get Info.

    Находясь в закладке General, нажмите кнопку Make File Localizable.

    iphone_5

    iphone_6

    Переключитесь обратно на закладку General, убедитесь, что локализация для языка проекта по умолчанию сформирована и добавьте еще один язык, нажав кнопку Add Localization, используя в качестве названия — ru

    iphone_7

    Если теперь вы заглянете через Finder в папку нашего проекта, то увидите две новых директории: English.lproj и ru.lproj, содержащие по копии файлов MainWindow.xib и Localizable.strings. Аналогичная группировка ресурсов по папкам видна и в XCode.

    iphone_8

    Процесс локализации строк прост до безумия. Откройте файл Localizable.strings из папки ru.lproj и впишите новое значение для подписи к кнопке возврата.

    "Done" = "Готово";  

    Просто, верно? С такой же легкостью мы сейчас создадим перевод для файла интерфейса. Процесс локализации nib-файлов проходит в Interface Builder. Локализатор переводит подписи к элементам интерфейса, заменяет звуковые и файлы изображений, также изменяет размеры тех или иных элементов на форме, если переведенный текст не помещается полностью в пределах их размеров.

    Откройте MainWindow.xib в Interface Builder и впишите новое значение для Back Button.

    iphone_9

    При локализации nib-файлов необходимо придерживаться условия — связи между объектами не должны быть нарушены в ходе процесса локализации.

    Вот и все. Запустите txtEdit. По умолчанию в симуляторе в качестве основного установлен английский язык и наше приложение использует англоязычные ресурсы для отображения данных. Стоит нам переключиться в Настройках на русский (Settings->General->International->Language), как надписи на кнопках сменятся на кириллицу.

    iphone_10

    Если изменение языка в Настройках не приводит к изменениям в интерфейсе, удалите папку build из директории вашего проекта и пересоберите приложение.

    На этом процесс локализации нашего приложения завершен, но для более сложных программ вам придется совершить немало дополнительных телодвижений. Я совершенно не затронул в своем посте тему приведения отображаемых данных в приложениях к формату выбранного региона, как то форматирование даты, чисел, денежных сумм и прочего — разобраться в этом помогут дополнительные источники информации, приведенные в конце статьи.

    Скачать архив проекта (28Кб)

    Дополнительные источники информации:

    Кстати, у меня уже была заметка про локализацию интерфейсов, где всуе упоминался Стив Джобс, но она была несколько иного рода.

    1. Selena

      Добрый день! Если Вы заинтересованы в локализации web-ПО, ПО для персональных компьютеров, ПО для мобильных устройств либо иного вида программного обеспечения, я рекомендую Вам использовать этот инструмент на базе web: https://poeditor.com/ POEditor является интуитивным, хорошо проработанным инструментом, обладающим рядом полезных свойств, которые помогают организовать процесс управления переводом. Он поддерживает множество популярных форматов файлов и обладает собственным API, что обеспечивает лучшую автоматизацию. Желаю Вам больших успехов в Ваших проектах!

      • Денис Хамин

        Мы пользуемся серверной версией MemoQ, она больше подходит для наших целей. Но спасибо за предложение.

    Добавить комментарий

    Войти с помощью: 

    Ваш e-mail не будет опубликован. Обязательные поля помечены *