Skip to main content

Повний посібник із локалізації застосунків iOS

Від Localizable.strings до метаданих App Store: локалізуйте свій застосунок iOS за допомогою Xcode, SwiftUI, Fastlane й автоматизованого перекладу на основі ШІ.

1

Увімкніть локалізацію в Xcode

Відкрийте налаштування свого проєкту Xcode, перейдіть до Info > Localizations і додайте мови, які бажаєте підтримувати. Xcode автоматично створить каталоги .lproj для кожної мови.

Xcode Project Settings
// In Xcode:
// 1. Select your project in the navigator
// 2. Go to Info tab > Localizations
// 3. Click + to add languages (e.g., German, Japanese)
// 4. Select which files to localize
//
// Xcode creates .lproj directories automatically:
// en.lproj/Localizable.strings
// de.lproj/Localizable.strings
// ja.lproj/Localizable.strings
Базова локалізація відокремлює Ваш інтерфейс від його рядків. Коли Ви додаєте мову, Xcode пропонує створити локалізовані версії Ваших файлів storyboard, XIB і файлів рядків.
2

Створіть Localizable.strings

Стандартний файл локалізації iOS містить пари «ключ — значення», розділені знаками рівності, а кожен рядок завершується крапкою з комою. Розмістіть його в папці Base.lproj для вихідної мови.

Base.lproj/Localizable.strings
// Base.lproj/Localizable.strings

"welcome_title" = "Welcome to MyApp";
"login_button" = "Sign In";
"settings_label" = "Settings";
"greeting" = "Hello, %@!";    // %@ = string placeholder
"item_count" = "%d items";     // %d = integer placeholder
Через відсутні крапки з комою виникають непомітні збої: файл завантажується без помилки, але переклади порожні. Також переконайтеся, що файл додано до етапу складання Copy Bundle Resources Вашої цілі, інакше його не буде включено до пакета застосунку.
Common .strings Mistakes
// ❌ Common mistakes in .strings files:

// Missing semicolon — file loads but translations are empty
"welcome_title" = "Welcome"

// Unescaped quotes — causes parse error
"message" = "Click "here" to continue";

// ✅ Correct versions:
"welcome_title" = "Welcome";
"message" = "Click \"here\" to continue";
3

Перейдіть на String Catalogs (Xcode 15+)

String Catalogs (.xcstrings) — сучасна заміна файлів .strings від Apple. Вони надають візуальний редактор у Xcode, автоматично видобувають рядки з Ваших подань SwiftUI та мають вбудовану підтримку форм множини.

Localizable.xcstrings
// Xcode 15+ String Catalog (Localizable.xcstrings)
// Xcode automatically extracts strings from your code
// and manages translations in a visual editor.

// In SwiftUI, strings are automatically localizable:
Text("Welcome to MyApp")
Text("Hello, \(userName)!")

// Mark strings explicitly:
let title = String(localized: "welcome_title")
String Catalogs зберігають УСІ мови в одному JSON-файлі .xcstrings. Для команд це означає часті конфлікти злиття Git, коли рядки одночасно додають кілька людей. Для великих проєктів варто використовувати окремий каталог для кожного модуля.
4

Використовуйте локалізовані рядки у SwiftUI та UIKit

Подання Text у SwiftUI автоматично локалізує рядкові літерали. UIKit використовує NSLocalizedString. В iOS 16+ сучасний API String(localized:comment:) пропонує зрозуміліший синтаксис із вбудованою підтримкою компілятора.

ContentView.swift
import SwiftUI

struct ContentView: View {
    let userName: String

    var body: some View {
        VStack {
            // ✅ SwiftUI auto-localizes string literals
            Text("welcome_title")

            // ⚠️ This does NOT localize (String interpolation)
            // Text("Hello, \(userName)")

            // ✅ Use String(localized:) for dynamic strings
            Text(String(localized: "greeting \(userName)"))

            // ✅ UIKit style (works everywhere)
            let title = NSLocalizedString(
                "settings_label",
                comment: "Settings screen title"
            )

            // ✅ Modern API (iOS 16+)
            let modern = String(
                localized: "welcome_title",
                comment: "Main screen title"
            )
        }
    }
}
Text("Hello \(name)") непомітно не локалізується, коли name — звичайна змінна String. Інтерполяція рядків SwiftUI створює LocalizedStringKey, однак правильно інтерполюються лише певні типи (Int, Double тощо). Для змінних String спочатку створіть локалізований рядок за допомогою String(localized:).
5

Опрацюйте форми множини

iOS використовує файли .stringsdict для правил множини й підтримує всі категорії множини CLDR: zero, one, two, few, many, other. У String Catalogs форми множини можна опрацьовувати у візуальному редакторі Xcode — це значно простіше, ніж писати XML stringsdict вручну.

Localizable.stringsdict
<!-- Localizable.stringsdict -->
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
    <key>items_count</key>
    <dict>
        <key>NSStringLocalizedFormatKey</key>
        <string>%#@count@</string>
        <key>count</key>
        <dict>
            <key>NSStringFormatSpecTypeKey</key>
            <string>NSStringPluralRuleType</string>
            <key>NSStringFormatValueTypeKey</key>
            <string>d</string>
            <key>zero</key>
            <string>No items</string>
            <key>one</key>
            <string>%d item</string>
            <key>other</key>
            <string>%d items</string>
        </dict>
    </dict>
</dict>
</plist>

// Usage in Swift:
String(format: NSLocalizedString("items_count", comment: ""),
       itemCount)
У таких мовах, як арабська, є 6 форм множини, у російській — 3, а в японській — 1. Завжди визначайте всі категорії CLDR, потрібні Вашим цільовим мовам. У String Catalogs це простіше завдяки візуальному редактору форм множини.
6

Локалізуйте метадані App Store за допомогою Fastlane

Використовуйте інструмент deliver із Fastlane, щоб зберігати метадані App Store — назву застосунку, підзаголовок, опис, ключові слова та примітки до випуску — у своєму репозиторії під контролем версій як звичайні текстові файли, упорядковані за локалями.

Terminal
# Install Fastlane
$ gem install fastlane

# Initialize deliver for App Store metadata
$ fastlane deliver init

# Directory structure created:
# fastlane/metadata/
# ├── en-US/
# │   ├── name.txt            # App name (30 chars)
# │   ├── subtitle.txt        # Subtitle (30 chars)
# │   ├── description.txt     # Full description
# │   ├── keywords.txt        # Search keywords (100 chars)
# │   ├── release_notes.txt   # What's New
# │   └── promotional_text.txt
# ├── de-DE/
# │   └── ...
# └── ja/
#     └── ...

# Push metadata to App Store Connect:
$ fastlane deliver
Перехресна локалізація: App Store у США індексує ключові слова як англійською, так і іспанською. Локалізація метаданих іспанською дає змогу охопити пошукові запити іспаномовних користувачів у США без орієнтації на окремий ринок.
7

Перевірте локалізацію

Перевіряйте локалізований вміст, не змінюючи мову пристрою. Використовуйте перевизначення схеми Xcode, щоб запускати застосунок будь-якою мовою, попередні перегляди SwiftUI із середовищем locale та XCUITest з аргументами запуску для автоматизованого тестування.

Testing Localization
// 1. Xcode Scheme Override:
// Edit Scheme > Run > Options > App Language > Choose language

// 2. SwiftUI Preview with locale:
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .environment(\.locale, Locale(identifier: "de"))

        ContentView()
            .environment(\.locale, Locale(identifier: "ja"))

        ContentView()
            .environment(\.locale, Locale(identifier: "ar"))
    }
}

// 3. XCUITest with language override:
let app = XCUIApplication()
app.launchArguments += ["-AppleLanguages", "(de)"]
app.launchArguments += ["-AppleLocale", "de_DE"]
app.launch()
Перевіряйте німецькою, де рядки приблизно на 30% довші за англійські, та японською, де вони приблизно на 50% коротші, щоб завчасно виявляти проблеми з компонуванням. Використовуйте псевдолокалізацію Xcode для стрес-тестування компонування без справжніх перекладів.

Автоматизуйте контроль якості перекладу

Виявляйте відсутні ключі, пошкоджені заповнювачі та проблеми з формами множини до випуску за допомогою i18n-validate. Перевіряйте свій інтерфейс із псевдоперекладами через i18n-pseudo ще до появи справжніх перекладів.
8

Автоматизуйте переклад

Перекладайте файли .strings, .xcstrings і метадані Fastlane за допомогою ШІ. Автоматизуйте переклад рядків у застосунку та метаданих App Store, щоб повністю локалізувати свою присутність.

Terminal
# Translate .strings files
> Translate Base.lproj/Localizable.strings
  to Japanese, German, and Spanish

# Translate App Store metadata too
> Translate fastlane/metadata/en-US/
  to de-DE, ja, es-MX

✓ 6 files translated in 3.2s
Локалізована сторінка в App Store збільшує кількість завантажень більш ніж на 30% на неангломовних ринках. Перекладайте метадані разом із рядками застосунку — це локалізація з найвищою окупністю.
+

Додатково: розумний резервний вибір локалі з LocaleChain

За замовчуванням iOS повертається до Вашої мови розробки, якщо точна локаль користувача недоступна. Користувач із локаллю pt-BR, для якого є лише переклади pt-PT, побачить англійську замість португальської. LocaleChain розв’язує цю проблему за допомогою налаштовуваних ланцюжків резервного вибору.

LocaleChain — пакет Swift із відкритим кодом. Переглянути на GitHub

Package Dependencies
// Swift Package Manager
// File > Add Package Dependencies >
// https://github.com/i18n-agent/ios-localechain.git
MyApp.swift
import LocaleChain

// In your App init or AppDelegate:
LocaleChain.configure()  // Activates all default chains

// pt-BR user with only pt-PT translations?
// → Shows Portuguese instead of falling back to English

// Custom overrides for your specific locales:
LocaleChain.configure(
    overrides: ["es-MX": ["es-419", "es"]]
)

Поширені помилки

Синтаксичні помилки у файлах .strings

Відсутні крапки з комою, неекрановані лапки або неправильне кодування спричиняють непомітні збої. Файл завантажується, але переклади відображаються порожніми. Завжди перевіряйте файли .strings перед створенням commit.

Інтерполяція Text у SwiftUI не локалізується

Text("Hello \(stringVar)") локалізується не так, як очікується. Використовуйте String(localized:) для обчислюваних рядків або переконайтеся, що інтерпольовані змінні мають правильний тип для LocalizedStringKey.StringInterpolation.

Віджети та розширення показують необроблені ключі

Розширення застосунку мають окремі пакети. Переконайтеся, що файли .strings або .xcstrings додано до етапу Copy Bundle Resources цілі розширення, а не лише до цілі основного застосунку.

У виробничому середовищі замість відсутніх перекладів показуються ключі

Коли для ключа немає перекладу мовою користувача, iOS показує сам ключ. Використовуйте стратегію резервної мови та перевіряйте всі підтримувані локалі перед випуском.

Рекомендована структура файлів

Project Structure
MyApp/
├── MyApp.xcodeproj
├── MyApp/
│   ├── Base.lproj/
│   │   ├── Localizable.strings       # Source strings
│   │   └── Localizable.stringsdict   # Plural rules
│   ├── en.lproj/
│   │   └── Localizable.strings
│   ├── de.lproj/
│   │   └── Localizable.strings
│   ├── ja.lproj/
│   │   └── Localizable.strings
│   ├── Localizable.xcstrings          # OR String Catalog
│   └── Info.plist
├── MyAppTests/
├── fastlane/
│   ├── Fastfile
│   └── metadata/
│       ├── en-US/
│       │   ├── name.txt
│       │   ├── description.txt
│       │   └── keywords.txt
│       ├── de-DE/
│       └── ja/
└── Package.swift

Спробуйте i18n Agent зараз

Перетягніть сюди файл для перекладу

JSON, YAML, PO, XML, CSV, Markdown, Properties

або натисніть, щоб вибрати

Цільові мови

Реєстрація не потрібнаМиттєвий розрахунок

Резервний вибір локалі з ios-localechain

Коли в регіональній локалі на кшталт de-AT немає ключа перекладу, iOS одразу переходить до мови розробки замість того, щоб спочатку перевірити батьківську локаль de.

Terminal
// Swift Package Manager
// https://github.com/i18n-agent/ios-localechain
Configuration
import LocaleChain

LocaleChain.configure(overrides: [
    "de": ["en-GB", "en"],
    "pt-BR": ["pt", "en"],
    "zh-Hant-HK": ["zh-Hant", "zh", "en"],
])

Перегляньте наш посібник із резервного вибору локалі, щоб ознайомитися з повним переліком підтримуваних фреймворків і 75 вбудованими ланцюжками. Learn more →

Поширені запитання про локалізацію iOS