Lingo.dev CLI 可通过已配置的 localization engine 翻译 Xcode 的 .xcstringsString Catalogs()。String Catalogs 是 Apple 在 Xcode 15 中推出的现代本地化格式,可将所有语言统一存储在一个 JSON 文件中。CLI 会直接原地更新这个文件——无需再按语言环境维护单独目录。
这篇指南将带你完整走通 iOS 应用本地化流程:配置 CLI、本地执行翻译,再借助 GitHub App 实现自动化,让每次 push 都能同步交付翻译。
演示仓库
克隆或 fork lingodotdev/ios-app-localization-example,边看边跟着操作。这个仓库内含一个可直接运行的 Xcode 项目,并已配置好 String Catalogs 和 Lingo.dev CLI。
String Catalogs 如何工作#
在 Xcode 15 之前,iOS 本地化需要在不同的 .strings 目录下分别管理 .stringsdict 和 [locale].lproj/ 文件。String Catalogs 用单个 Localizable.xcstrings 文件取代了这种方式,并由 Xcode 自动维护。
当你在 SwiftUI 或 UIKit 中将字符串标记为可本地化时,Xcode 会在构建过程中自动识别,并将其加入 String Catalog。每个条目都会记录源字符串、各个已配置语言环境下的翻译,以及一个可选注释字段,用来为译者提供上下文。
| 对比项 | 旧版 .strings | String Catalogs .xcstrings |
|---|---|---|
| 文件数量 | 每个语言环境、每个表各一份 | 单个文件,包含所有语言环境 |
| 格式 | 键值文本 | 结构化 JSON |
| 复数支持 | 单独的 .stringsdict 文件 | 内建复数规则 |
| Xcode 集成 | 手动导出/导入 | 自动识别 |
| 译者注释 | 不支持 | 每个条目都有注释字段 |
CLI 会根据文件扩展名识别 .xcstrings 格式,解析其中的 JSON 结构,通过本地化引擎翻译每个条目,再将译文写回同一个文件——同时保留注释、复数规则和元数据。
前提条件#
创建 localization engine
确认 Node.js 版本
CLI 需要 Node.js 22 或更高版本:
node -v在 Xcode 中启用本地化
在 Xcode 项目中,进入 Project Settings > Info > Localizations,添加目标语言。你每添加一个语言环境,Xcode 就会为其创建对应的 String Catalog 条目。更多细节可参考 Apple 的 localization documentation。
安装并配置 CLI#
先安装 CLI、完成身份验证,再配置项目。完整步骤可参考 Quickstart。
npm install -g @lingo.dev/cli
lingo login在项目根目录运行 lingo init,并根据提示回答问题(源语言环境、目标语言环境,以及指向 String Catalog 的文件匹配模式);然后再运行 lingo link,将项目绑定到你的组织和引擎。两步操作会共同生成一个 .lingo/config.json:
{
"orgId": "org_...",
"engineId": "eng_...",
"sourceLocale": "en",
"targetLocales": ["es", "fr", "de", "ja"],
"files": [{ "pattern": "MyApp/Localizable.xcstrings" }]
}请提交 .lingo/config.json——它是决定哪些内容会被翻译的唯一事实来源。.xcstrings 格式会根据文件扩展名自动识别。由于 String Catalogs 会将所有语言环境存放在同一个文件中,因此匹配模式里不需要语言环境占位符:CLI 会读取源语言条目,并将所有目标语言写回同一个文件。完整 schema 请参阅 configuration reference。
多个 String Catalogs
如果你的项目使用了多个 String Catalog 文件(例如每个 framework target 对应一个),请为每个文件分别添加一条 files:
{
"files": [
{ "pattern": "MyApp/Localizable.xcstrings" },
{ "pattern": "MyAppWidgets/Localizable.xcstrings" }
]
}本地执行翻译#
在项目根目录运行首次翻译:
lingo push --backfill-missingCLI 会读取你的 String Catalog,通过本地化引擎翻译所有缺失条目,等待任务完成后,再将结果写回 .xcstrings 文件。在 Xcode 中打开该文件,即可看到每个已配置语言环境的翻译已自动填入。
编辑源字符串后,直接运行 lingo push 只会翻译增量内容——源文未变化的条目会在服务端自动跳过,并通过 lockfile 进行追踪:
lingo push译者注释#
String Catalogs 支持为每个条目添加注释字段,CLI 会在发起翻译请求时一并带上。这些注释能为 localization engine 提供上下文——帮助消除术语歧义、明确语气,或说明字符串在 UI 中出现的位置。
在 Xcode 中,选中 String Catalog 编辑器里的某个字符串,然后在检查器面板中添加注释。该注释会存储在 .xcstrings JSON 中:
{
"sourceLanguage": "en",
"strings": {
"Set": {
"comment": "Refers to a collection of items, not the verb",
"localizations": { }
}
}
}CLI 会将这条注释与字符串一起发送,从而引导模型做出更准确的理解。比如 “Set” 如果缺少上下文,在很多语言里可能会被翻成动词;而注释可以消除这种歧义。更多用法可参阅 Translator Notes。
复数#
String Catalogs 基于 CLDR plural rules 原生支持复数形式。当你在 Xcode 中定义复数变体时,String Catalog 会为目标语言所需的各个复数类别存储规则(zero、one、two、few、many、other)。
CLI 会在翻译过程中保留这一结构,并为每个目标语言环境生成正确的复数类别。英语只用两类(one 和 other),但阿拉伯语需要六类,波兰语需要四类,日语则只需要一类。localization engine 会自动处理这些差异。
使用 GitHub App 实现自动化#
在你的仓库中安装 Lingo.dev GitHub App,即可实现持续本地化——无需自行管理 CI runner、API key secret 或 lockfile。安装完成并指向你的 .lingo/config.json(以及其中的 engineId)后,它就会自动响应 push 和 pull request:检测发生变化的源字符串,通过你的引擎完成翻译,并将更新后的 .xcstrings 提交回分支,或直接发起一个 pull request。
想自己运行?
你也可以在自己的 CI 任务中运行 lingo push(任何装有 Node.js 的 runner 都可以),并提交结果,使用 LINGO_API_KEY 完成身份验证。若想了解基于 runner 的方案,请参阅 CI/CD Workflows。
部署前先校验#
将 lingo check 作为部署前的质量门禁,确保未翻译的字符串不会进入生产环境。当仍有缺失或过期的翻译待处理时,它会输出报告,并以非零状态码退出:
lingo check在构建前,将它作为一个独立的 CI 步骤加入流程中。
