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) са съвременният заместител на Apple на файловете .strings. Те предлагат визуален редактор в 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 — много по-лесно от ръчното писане на stringsdict XML.

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 със зададена езикова среда и 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, преди да запишете промените в Git.

Интерполацията в 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