Skip to main content

Panduan Lengkap Penyetempatan Aplikasi iOS

Daripada Localizable.strings hingga metadata App Store: setempatkan aplikasi iOS dengan Xcode, SwiftUI, Fastlane, dan terjemahan AI automatik.

1

Aktifkan Penyetempatan dalam Xcode

Buka tetapan projek Xcode, pergi ke Info > Localizations, kemudian tambahkan bahasa yang mahu anda sokong. Xcode mencipta direktori .lproj untuk setiap bahasa secara automatik.

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
Penyetempatan asas memisahkan UI daripada rentetannya. Apabila menambahkan bahasa, Xcode menawarkan untuk mencipta versi setempat papan cerita, XIB, dan fail rentetan anda.
2

Cipta Localizable.strings

Fail penyetempatan iOS standard menggunakan pasangan kekunci-nilai yang dipisahkan tanda sama dengan, dengan setiap baris diakhiri koma bernoktah. Letakkan fail dalam folder Base.lproj untuk bahasa sumber.

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
Koma bernoktah yang hilang menyebabkan kegagalan tanpa mesej—fail dimuatkan tanpa ralat, tetapi terjemahan kosong. Pastikan juga fail ditambahkan pada fasa binaan Copy Bundle Resources sasaran anda atau fail tidak akan disertakan dalam bundle aplikasi.
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

Pindahkan ke String Catalog (Xcode 15+)

String Catalog (.xcstrings) ialah pengganti moden fail .strings daripada Apple. Format ini menyediakan editor visual dalam Xcode, pengekstrakan rentetan automatik daripada paparan SwiftUI, dan sokongan bentuk jamak terbina dalam.

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 Catalog menyimpan SEMUA bahasa dalam satu fail JSON .xcstrings. Dalam pasukan, perkara ini kerap menyebabkan konflik gabungan Git apabila beberapa orang menambahkan rentetan. Untuk projek besar, pertimbangkan satu katalog bagi setiap modul.
4

Gunakan Rentetan Setempat dalam SwiftUI dan UIKit

Paparan Text SwiftUI menyetempatkan literal rentetan secara automatik. UIKit menggunakan NSLocalizedString. Untuk iOS 16+, API moden String(localized:comment:) menyediakan sintaks yang lebih kemas dengan sokongan pengkompil terbina dalam.

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)") gagal melakukan penyetempatan tanpa mesej apabila name ialah pemboleh ubah String biasa. Interpolasi rentetan SwiftUI mencipta LocalizedStringKey, tetapi hanya jenis tertentu (Int, Double, dan lain-lain) diinterpolasi dengan betul. Untuk pemboleh ubah String, gunakan String(localized:) untuk membina rentetan setempat terlebih dahulu.
5

Kendalikan Bentuk Jamak

iOS menggunakan fail .stringsdict untuk peraturan bentuk jamak dan menyokong semua kategori bentuk jamak CLDR: zero, one, two, few, many, other. String Catalog mengendalikan bentuk jamak dengan editor visual dalam Xcode—jauh lebih ringkas daripada menulis XML stringsdict secara manual.

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)
Bahasa seperti Arab mempunyai 6 bentuk jamak, Rusia 3, dan Jepun 1. Sentiasa takrifkan semua kategori CLDR yang diperlukan oleh bahasa sasaran. String Catalog memudahkannya dengan editor bentuk jamak visual.
6

Setempatkan Metadata App Store dengan Fastlane

Gunakan alat deliver Fastlane untuk menyimpan metadata App Store—nama aplikasi, sari kata, penerangan, kata kunci, nota keluaran—sebagai fail teks biasa yang dikawal versi dalam repositori dan disusun mengikut bahasa.

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
Penyetempatan silang: App Store AS mengindeks kata kunci bahasa Inggeris dan Sepanyol. Menyetempatkan metadata kepada bahasa Sepanyol mencapai carian pengguna Hispanik di AS tanpa menyasarkan pasaran berasingan.
7

Uji Penyetempatan anda

Uji kandungan setempat tanpa mengubah bahasa peranti. Gunakan penggantian skema Xcode untuk menjalankan aplikasi dalam sebarang bahasa, pratonton SwiftUI dengan persekitaran bahasa, dan XCUITest dengan argumen pelancaran untuk ujian automatik.

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()
Uji dengan bahasa Jerman (rentetan memanjang kira-kira 30% berbanding bahasa Inggeris) dan Jepun (rentetan memendek kira-kira 50%) untuk mengesan masalah susun atur lebih awal. Gunakan penyetempatan pseudo Xcode untuk menguji susun atur secara ekstrem tanpa terjemahan sebenar.

Automatikkan Kualiti Terjemahan

Kesan kekunci hilang, ruang letak rosak, dan masalah bentuk jamak sebelum dikeluarkan dengan i18n-validate. Uji UI dengan terjemahan pseudo menggunakan i18n-pseudo sebelum terjemahan sebenar tersedia.
8

Automatikkan Terjemahan

Terjemah fail .strings, .xcstrings, dan metadata Fastlane dengan AI. Automatikkan terjemahan rentetan dalam aplikasi dan metadata App Store untuk menyediakan pengalaman yang disetempatkan sepenuhnya.

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
Kehadiran App Store yang disetempatkan meningkatkan muat turun lebih daripada 30% dalam pasaran bukan bahasa Inggeris. Terjemah metadata bersama rentetan aplikasi—ini ialah penyetempatan dengan ROI tertinggi yang boleh anda lakukan.
+

Bonus: Sandaran Bahasa Pintar dengan LocaleChain

Secara lalai, iOS beralih kepada bahasa pembangunan apabila bahasa tepat pengguna tiada. Pengguna pt-BR yang hanya mempunyai terjemahan pt-PT akan melihat bahasa Inggeris, bukan Portugis. LocaleChain membaikinya dengan rantaian sandaran yang boleh dikonfigurasi.

LocaleChain ialah pakej Swift sumber terbuka. Lihat di 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"]]
)

Kesilapan Umum

Ralat Sintaks Fail .strings

Koma bernoktah yang hilang, tanda petik yang tidak dilepaskan, atau pengekodan yang salah menyebabkan kegagalan tanpa mesej. Fail dimuatkan, tetapi terjemahan kelihatan kosong. Sentiasa sahkan fail .strings sebelum commit.

Interpolasi Text SwiftUI Tidak Disetempatkan

Text("Hello \(stringVar)") tidak disetempatkan seperti yang dijangka. Gunakan String(localized:) untuk rentetan terhitung atau pastikan pemboleh ubah interpolasi mempunyai jenis yang betul untuk LocalizedStringKey.StringInterpolation.

Widget/Sambungan Memaparkan Kekunci Mentah

Sambungan aplikasi mempunyai bundle berasingan. Pastikan fail .strings atau .xcstrings ditambahkan pada fasa Copy Bundle Resources sasaran sambungan, bukan hanya sasaran aplikasi utama.

Terjemahan yang Hilang Memaparkan Kekunci dalam Pengeluaran

Apabila kekunci tidak mempunyai terjemahan untuk bahasa pengguna, iOS memaparkan kekunci itu sendiri. Gunakan strategi bahasa sandaran dan uji semua bahasa yang disokong sebelum keluaran.

Struktur Fail yang Disyorkan

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

Cuba i18n Agent Sekarang

Lepaskan fail terjemahan anda di sini

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

atau klik untuk semak imbas

Bahasa sasaran

Tidak perlu mendaftarAnggaran serta-merta

Sandaran Bahasa dengan ios-localechain

Apabila kekunci terjemahan tiada dalam bahasa serantau seperti de-AT, iOS terus beralih kepada bahasa pembangunan dan bukannya memeriksa bahasa induk de terlebih dahulu.

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"],
])

Lihat Panduan Sandaran Bahasa kami untuk senarai lengkap rangka kerja yang disokong dan 75 rantaian terbina dalam. Learn more →

Soalan Lazim Penyetempatan iOS