本地化|使用 String Catalog 为应用添加多语言

了解如何使用 String Catalog 实现本地化管理,并借助编译器自动提取 Swift 字符串,实现高效、集中化的多语言支持。

String Catalog(字符串目录)是 Apple 在 WWDC 2023 推出的新本地化系统,用于替代传统的 .strings.stringsdict 文件。

创建 String Catalog 文件

Localizable.xcstrings 就是一个集中管理所有语言版本的文件,以便系统能够正确调用。File → New → File from Template,选择 String Catalog,命名为 Localizable.xcstrings。

启用 Use Compiler to Extract Swift Strings 选项

"Use Compiler to Extract Swift Strings" 的具体作用是让编译器在构建时自动扫描和提取代码中的可本地化字符串。

当我们在代码中写:

Text("Hello World") // SwiftUI
String(localized: "welcome_message")
NSLocalizedString("submit_button", comment: "")

开启此选项后,Build 时这些字符串会自动出现在 Localizable.xcstrings 中,无需手动添加。

该选项默认启用,可以在 Build Settings 中设置。

构建项目提取字符串

至少 Build 一次项目,确保让 Xcode 自动扫描并提取所有可本地化字符串,并自动添加到 String Catalog。

设置 @Environment(.locale) 环境值

SwiftUI 提供了 .locale 环境值,用于设置 App 当前使用的语言。

  • 创建一个 LocalizationManager 类,存储用户选择的语言。最佳实践是通过 UserDefaults 来持久化。
  • 在 App 文件中,通过 .environment(.locale, LocalizationManager.shared.locale) 设置 locale 值即可,就这么简单。
@main
struct MyApp: App {
    private var localizationManager: LocalizationManager {
        LocalizationManager.shared
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(settings)
                .environment(\.locale, localizationManager.locale)
        }
    }
}

在枚举中使用 String Catalog

在枚举中,关键是使用 LocalizedStringKey 而不是 String,这样 SwiftUI
才能够正确处理本地化。

enum DayRange: String, CaseIterable, Identifiable {
    case fourteen
    case ninety
    case allTime
    
    var localized: LocalizedStringKey {
        switch self {
        case .fourteen:
            "14 Days"
        case .ninety:
            "90 Days"
        case .allTime:
            "All Time"
        }
    }
    
    var id: String { self.rawValue }
}