Почему локализация — это не просто перевод
Многие думают: отдал файлы переводчику, вставил строки — и готово. На практике это работает примерно так же, как «выучить английский за 30 дней по приложению».
Локализация (l10n) — это адаптация продукта под конкретный рынок: язык, форматы дат и чисел, направление текста, культурные особенности, иногда даже цвета. Перевод — лишь часть этой работы.
По данным App Annie, 70% загрузок в App Store приходится на страны, где английский не является основным языком. Конверсия в загрузку растёт на 26% после добавления описания на родном языке пользователя. Это не абстрактная статистика — это деньги, которые утекают мимо.
Как устроена локализация в Xcode
iOS предоставляет удобную инфраструктуру из коробки. Базовый механизм — файлы .strings и .stringsdict.
Файлы .strings
Каждая строка в приложении получает уникальный ключ:
let title = NSLocalizedString("onboarding.welcome.title", comment: "Заголовок экрана онбординга")
В директории en.lproj лежит Localizable.strings:
"onboarding.welcome.title" = "Welcome to the App";
В ru.lproj — его русский аналог:
"onboarding.welcome.title" = "Добро пожаловать";
iOS сам выбирает нужный файл по языку устройства.
String Catalogs — новый подход с Xcode 15
В Xcode 15 появился String Catalog — формат .xcstrings. Это JSON-файл, который хранит все языки сразу и показывает состояние перевода прямо в редакторе: зелёная галочка — переведено, жёлтый значок — устарело, красный — не переведено.
Мигрировать со старого формата легко: Edit → Convert → To String Catalog, и Xcode сделает всё сам.
Множественные числа — самое неприятное место
В английском два варианта: «1 item» и «2 items». В русском — четыре: «1 элемент», «2 элемента», «5 элементов», «21 элемент». В арабском — шесть форм. В китайском — одна.
Для этого существует .stringsdict — XML-файл, описывающий правила для каждого языка:
<key>items.count</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@items@</string>
<key>items</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>d</string>
<key>one</key>
<string>%d элемент</string>
<key>few</key>
<string>%d элемента</string>
<key>many</key>
<string>%d элементов</string>
<key>other</key>
<string>%d элемента</string>
</dict>
</dict>
Ошибка, которую делают почти все — пишут в коде что-то вроде:
// Так делать нельзя
let text = count == 1 ? "1 товар" : "\(count) товаров"
Это работает только для русского и только если разработчик помнит про 21, 22, 11, 12. Обычно не помнит — и появляется «21 товаров».
Форматирование дат, чисел и валюты
В США дата выглядит так: 06/10/2026. В России — 10.06.2026. В Японии — 2026年6月10日. Если захардкодить формат — кто-то обязательно увидит что-то странное.
Используй DateFormatter с локалью:
let formatter = DateFormatter()
formatter.dateStyle = .long
formatter.locale = Locale.current
let dateString = formatter.string(from: date)
То же самое с числами и валютой:
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.locale = Locale.current
let price = formatter.string(from: 9.99)
В США получим $9.99, в России — 9,99 ₽, в Германии — 9,99 €. Никакого хардкода, никаких проблем.
RTL — языки справа налево
Арабский и иврит читаются справа налево. Если думаешь, что это просто «текст в другую сторону» — нет. Весь интерфейс зеркалируется: кнопка «назад» переходит направо, иконки меняют положение, вся вёрстка переворачивается.
Хорошая новость: iOS делает большую часть работы автоматически, если используешь Auto Layout с Leading/Trailing вместо Left/Right. Это правило номер один при вёрстке под RTL.
// Правильно
view.leadingAnchor.constraint(equalTo: container.leadingAnchor)
// Неправильно — сломается в RTL
view.leftAnchor.constraint(equalTo: container.leftAnchor)
Для кастомных иконок с направленностью (стрелки, кнопки «вперёд/назад») добавь флаг зеркального отображения:
image.imageFlipsForRightToLeftLayoutDirection = true
Проверяй RTL прямо в симуляторе: Settings → General → Language & Region → установи Arabic.
Культурные нюансы: когда перевод не спасает
Текст переведён правильно, интерфейс зеркален — но приложение всё равно выглядит чужеродно. Потому что локализация — это ещё и культурная адаптация.
Несколько примеров:
- Цвет белый в азиатских культурах ассоциируется с трауром, а не чистотой.
- Имена в США: имя + фамилия. В Японии: фамилия + имя. Форма с полями «First Name» / «Last Name» ставит японского пользователя в тупик.
- Жест «большой палец вверх» — нейтральный в США, оскорбительный в ряде стран Ближнего Востока.
- Номер телефона в разных странах имеет разную длину и формат — валидация «10 цифр» сломает регистрацию для половины мира.
Это мелочи, но именно они создают ощущение «своего» продукта.
Локализация в App Store
Люди находят приложение ещё до того, как его скачают. Страница в App Store — тоже часть локализации.
Что нужно перевести:
- Название приложения
- Подзаголовок
- Описание
- Ключевые слова (по 100 символов на язык, каждое слово работает независимо)
- Скриншоты — текст на них тоже должен быть на нужном языке
Особенно важны скриншоты. Пользователь листает выдачу, видит непонятный текст — и проходит мимо. Перевести описание дёшево, перерисовать скриншоты трудоёмко, но необходимо.
Ключевые слова в App Store индексируются по каждому рынку независимо. То, что работает для США, может не работать для Германии. Для анализа ключевых слов по странам используй AppFollow или Sensor Tower.
Инструменты и автоматизация
Экспорт и импорт переводов
Xcode умеет экспортировать все строки в формат XLIFF — его понимают большинство бюро переводов и CAT-инструментов (SDL Trados, memoQ):
xcodebuild -exportLocalizations -localizationPath ./Localizations -project App.xcodeproj
После перевода импортируй обратно:
xcodebuild -importLocalizations -localizationPath ./Localizations/ru.xcloc -project App.xcodeproj
Сервисы для управления переводами
- Lokalise — удобная интеграция с Xcode, GitHub и GitLab. Переводчики работают в браузере, разработчики получают файлы через API или GitHub Actions.
- Phrase — популярен в корпоративном сегменте.
- POEditor — бюджетный вариант для небольших приложений.
- Crowdin — удобен для open-source проектов, есть бесплатный план.
Для приложения с одним-двумя языками хватит ручного XLIFF-экспорта. Для продукта с постоянными обновлениями Lokalise окупается быстро.
Pseudo-localization для тестирования вёрстки
Все строки заменяются похожими символами, которые занимают больше места: «Hello» превращается в «[Héllö Wörld!!!]». Смысл — найти проблемы с вёрсткой до прихода реальных переводов.
Немецкий в среднем на 30% длиннее английского. Финский — иногда вдвое. Если кнопка рассчитана ровно под английский текст — в немецком она сломается.
Включается через схему запуска: Edit Scheme → Options → App Language → Accented Pseudo-Language.
Типичные ошибки
Конкатенация строк. Никогда не склеивай переведённые части:
// Плохо — в других языках порядок слов будет другим
let text = "У вас " + count + " " + NSLocalizedString("messages", ...)
// Хорошо — format specifiers
let format = NSLocalizedString("messages.count", comment: "")
let text = String(format: format, count)
// messages.count = "У вас %d сообщений"
Картинки с текстом. Если в дизайне есть изображение с надписью — её нужно либо убрать, либо делать отдельную версию для каждой локали.
Предположения о длине строки. «Username» — 8 символов. «Benutzername» — 12. «Käyttäjänimi» (финский) — 12. Делай поля и кнопки гибкими.
Перевод без контекста. Переводчик получает ключи вроде button.ok, title.main, label.empty. Без контекста непонятно: это кнопка подтверждения платежа или удаления данных. Используй поле comment в NSLocalizedString — оно именно для этого.
Хардкод локали. Иногда разработчик явно пишет Locale(identifier: "en_US") для форматирования. Это ломает всё для всех остальных.
Когда и как выходить на новый рынок
Минимальный старт. Локализовать только самые важные экраны — онбординг, платёжный флоу, настройки. Остальное оставить на английском. Лучше, чем ничего, и позволяет проверить спрос.
A/B тест перед вложениями. Выпусти приложение в новой стране на английском, посмотри органику за месяц. Если есть загрузки — локализуй и сравни конверсию.
Приоритет по объёму рынка. Топ рынков по загрузкам в App Store: США, Китай, Япония, Германия, Великобритания, Франция, Бразилия. Китай требует отдельного внимания — там свои правила дистрибуции и нужен местный партнёр.
Машинный перевод как черновик. DeepL даёт хорошее качество для европейских языков. Используй его как черновик, который потом правит носитель языка — экономия в 3-5 раз по сравнению с переводом с нуля.
Ориентир по стоимости: профессиональный перевод 1000 слов стоит 50-150 долларов в зависимости от языка. Японский и арабский дороже европейских.
Как организовать процесс
Хорошая локализация — не разовый спринт, а постоянный процесс. Несколько правил, которые работают:
- Каждая новая строка сразу получает ключ и комментарий — не «потом добавим», а сейчас.
- Переводы обновляются вместе с релизом, не после.
- Есть ответственный — разработчик или PM, который следит за полнотой.
- CI/CD проверяет отсутствие непереведённых строк перед сборкой. Инструмент
swiftgen или простой скрипт с проверкой .xcstrings справится с задачей.
Если нужна помощь с организацией переводного процесса или автоматизацией рутины — в REEXY занимаются интеграцией подобных решений в рамках разработки и поддержки мобильных проектов.
Главное
Технически iOS даёт всё необходимое: String Catalogs, .stringsdict для множественных чисел, автоматическое RTL, форматтеры с локалью. Нужно только правильно использовать это с самого начала.
Самая дорогая локализация — та, которую делают в конце проекта на уже выпущенном приложении. Заложить правильную архитектуру строк с первого дня — не сложно и не долго. Зато потом не придётся переделывать половину кода, чтобы выйти на рынок, который мог бы приносить деньги уже сейчас.