Интернационализация (i18n) в Swift: полное руководство для iOS и macOS
Интернационализация (i18n) — это процесс проектирования приложения таким образом, чтобы оно могло быть адаптировано для различных языков и регионов без инженерных изменений. В экосистеме Apple (iOS, macOS, watchOS, tvOS) инструменты для локализации встроены непосредственно в Swift и Xcode. В этой статье мы подробно разберем, как использовать NSLocalizedString и современный String Catalog для создания мультиязычных приложений.
Основы: NSLocalizedString
Базовый механизм интернационализации в Swift — это функция NSLocalizedString. Она ищет перевод строки в файлах .strings или .xcstrings (String Catalog).
let greeting = NSLocalizedString("hello_world", comment: "Приветствие на главном экране")
print(greeting) // Выведет перевод в зависимости от языка устройства
Параметр comment служит подсказкой для переводчика. Ключ "hello_world" должен быть уникальным в рамках всего проекта.
Создание файлов локализации
В Xcode вы можете добавить поддерживаемые языки через Project Info > Localizations. После этого для каждого .strings файла или Storyboard будут созданы подфайлы локализации.
Пример содержимого Localizable.strings (английский):
"hello_world" = "Hello, World!";
"welcome_message" = "Welcome to our app %@";
Русская версия (Localizable.strings (Russian)):
"hello_world" = "Привет, мир!";
"welcome_message" = "Добро пожаловать в наше приложение %@";
Форматирование строк с параметрами
Для строк, содержащих динамические данные, используйте спецификаторы формата. В Swift это можно делать двумя способами:
Способ 1: String(format:)
let userName = "Иван"
let points = 150
let message = String(format: NSLocalizedString("user_score", comment: "Очки пользователя"), userName, points)
print(message) // "Иван набрал 150 очков"
В файле локализации:
"user_score" = "%@ набрал %d очков";
Способ 2: Swift String Interpolation (iOS 15+)
let message = "\(userName) набрал \(points) очков"
Однако этот способ не подходит для локализации, так как порядок слов в разных языках может отличаться. Используйте только String(format:) или AttributedString с инфлекцией.
Плюризация (множественные формы)
В русском языке есть сложные правила склонения: "1 файл", "2 файла", "5 файлов". Для этого Apple предоставляет stringsdict (XML) или String Catalog с правилами плюризации.
Пример stringsdict
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>files_count</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@files@</string>
<key>files</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>
</dict>
</plist>
Использование в коде:
let count = 3
let text = String.localizedStringWithFormat(
NSLocalizedString("files_count", comment: "Количество файлов"),
count
) // "3 файла"
String Catalog (xcstrings) — современный подход
Начиная с Xcode 15, Apple рекомендует использовать String Catalog вместо старых