Skip to main content

คู่มือโลคัลไลเซชันแอป iOS อย่างครบถ้วน

ตั้งแต่ Localizable.strings จนถึงเมทาดาทา App Store ทำโลคัลไลเซชันแอป iOS ด้วย Xcode, SwiftUI, Fastlane และการแปลอัตโนมัติด้วย AI

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
Base localization แยก UI ออกจากข้อความ เมื่อเพิ่มภาษา 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 Catalog (Xcode 15+)

String Catalog (.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 Catalog เก็บทุกภาษาไว้ในไฟล์ JSON แบบ .xcstrings ไฟล์เดียว สำหรับทีม วิธีนี้ทำให้เกิดข้อขัดแย้งขณะผสาน Git บ่อยครั้งเมื่อหลายคนเพิ่มข้อความ โปรเจกต์ขนาดใหญ่ควรพิจารณาแยกหนึ่ง Catalog ต่อโมดูล
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 Catalog จัดการพหูพจน์ด้วยเครื่องมือแก้ไขผ่านภาพใน 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 Catalog ช่วยให้ทำได้ง่ายขึ้นด้วยเครื่องมือแก้ไขพหูพจน์ผ่านภาพ
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

ทดสอบโลคัลไลเซชัน

ทดสอบเนื้อหาที่โลคัลไลซ์โดยไม่เปลี่ยนภาษาของอุปกรณ์ ใช้การแทนค่า scheme ของ Xcode เพื่อรันแอปในภาษาใดก็ได้ ใช้พรีวิว SwiftUI พร้อม environment ภาษา และใช้ 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 จับคีย์ที่หายไป ตัวยึดตำแหน่งเสียหาย และปัญหาพหูพจน์ก่อนส่งขึ้นใช้งาน แล้วทดสอบ UI ด้วยคำแปลจำลองผ่าน i18n-pseudo ก่อนคำแปลจริงจะมาถึง
8

ทำให้การแปลเป็นอัตโนมัติ

แปลไฟล์ .strings, .xcstrings และเมทาดาทา Fastlane ด้วย AI ทำให้การแปลทั้งข้อความในแอปและเมทาดาทา 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 ก่อนคอมมิตเสมอ

การแทรกค่าใน 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