用途
App Localization 用于管理基于 Tuist 的 iOS/macOS 项目中的 .strings 本地化文件。它适用于以下场景:向模块添加新的翻译键、校验翻译一致性、将 Swift 代码中的硬编码字符串替换为类型安全的本地化访问器,以及为多语言环境生成翻译。
项目结构
该技能假设项目采用如下结构:
<ModuleName>/
├── Resources/
│ ├── en.lproj/Localizable.strings # 主语言(英语)
│ ├── <locale>.lproj/Localizable.strings # 其他语言
│ └── ...
├── Derived/
│ └── Sources/
│ └── TuistStrings+<ModuleName>.swift # 由 Tuist 生成
└── Sources/
└── **/*.swift # 使用 <ModuleName>Strings.Section.key
编辑 .strings 文件后,需运行 tuist generate 重新生成类型安全访问器。
主要能力
完整本地化工作流
- 识别硬编码字符串:通过 grep 在 Swift 文件中查找
Text("...")、title: "..."、label: "..."、placeholder: "..."等模式。 - 添加翻译键:向所有语言文件添加键值,主语言为 en.lproj/Localizable.strings,其他语言做相应翻译。
- 生成类型安全访问器:运行
tuist generate,生成 Derived/Sources/TuistStrings+<ModuleName>.swift,提供静态属性(如<ModuleName>Strings.Section.keyName)和带参数的静态函数(如<ModuleName>Strings.Section.keyWithParam(value))。 - 更新 Swift 代码:将硬编码字符串替换为生成的访问器。
- 校验变更:构建项目以捕获缺失键,并运行校验脚本检查一致性。
模式映射
| 硬编码模式 | 本地化模式 |
|---|---|
Text("Title") |
Text(<Module>Strings.Section.title) |
Text("Hello, \(name)") |
Text(<Module>Strings.Section.hello(name)) |
title: "Submit" |
title: <Module>Strings.Action.submit |
placeholder: "Enter..." |
placeholder: <Module>Strings.Field.placeholder |
参数与复数处理
- 带参数:键
"search.noResults" = "No results for \"%@\""对应Text(<Module>Strings.Search.noResults(searchText))。 - 条件复数:使用
item.count与item.countPlural两个键,在 Swift 中根据数量选择。 - 多参数:键
"message.detail" = "%@ uploaded %d files"对应Text(<Module>Strings.Message.detail(userName, fileCount))。
AI 辅助翻译
翻译到非英语语言时,技能要求:读取英语源字符串;根据键名推断上下文;按目标语言习惯翻译(如 zh-Hans 简体中文正式而友好、zh-Hant 繁体中文、ja 日语敬体、ko 韩语敬体、de/fr/es 等遵循地区惯例);精确保留所有占位符(%@、%d、%ld 等)。不同 UI 元素的翻译风格:标签保持简洁、按钮使用动作导向动词、占位符使用指导性语气、错误消息清晰有帮助、确认信息明确后果。
校验脚本
python scripts/validate_strings.py /path/to/<ModuleName>:检查语言间缺失键、重复键、占位符不匹配、未翻译字符串(值等于英语)。python scripts/sync_translations.py /path/to/<ModuleName> --report:报告缺失键。python scripts/sync_translations.py /path/to/<ModuleName> --sync:将缺失键添加为占位符。
使用方式
键命名规范
模式为 "domain.context.element",对应 <Module>Strings.Domain.Context.element。键应反映用户正在做什么,而非技术 UI 组件。
| 用户心智模型 | 键模式 | 生成的访问器 |
|---|---|---|
| "我在看我的个人资料" | profile.name |
Strings.Profile.name |
| "我在测试一个构建" | betaBuild.whatToTest |
Strings.BetaBuild.whatToTest |
| "我在添加测试者" | testerGroup.addTester |
Strings.TesterGroup.addTester |
| "同步出了问题" | sync.error.failed |
Strings.Sync.Error.failed |
好例子(领域导向)与坏例子(技术导向)对比:profile.save 优于 button.save;registration.email 优于 field.email;appSelector.searchPlaceholder 优于 placeholder.search;sync.connectionFailed 优于 error.network;settings.title 优于 label.title;build.expireConfirm 优于 alert.confirm。
键按功能或屏幕组织,例如:
/* Profile Section */
"profile.title" = "Profile";
"profile.name" = "Name";
"profile.save" = "Save Changes";
"profile.saveSuccess" = "Profile updated";
/* Beta Builds */
"betaBuild.title" = "Beta Builds";
"betaBuild.whatToTest" = "What to Test";
"betaBuild.submitForReview" = "Submit for Review";
"betaBuild.expireConfirm" = "Expire this build?";
/* Tester Groups */
"testerGroup.create" = "Create Group";
"testerGroup.addTester" = "Add Tester";
"testerGroup.empty" = "No testers yet";
.strings 文件格式
/* Comment describing the section */
"key.name" = "Value";
"key.with.parameter" = "Hello, %@!";
"key.with.number" = "%d items";
"key.with.multiple" = "%1$@ has %2$d items";
规则:键在文件内必须唯一;值为 UTF-8 编码;用反斜杠转义引号 \";行以分号结尾;当语言间参数顺序不同时使用位置参数(%1$@、%2$d)。
适用场景
- 向 Tuist 项目的模块添加新翻译键。
- 校验多语言 .strings 文件的一致性。
- 将 Swift 代码中的硬编码字符串迁移为类型安全访问器。
- 为 iOS/macOS 应用生成多语言翻译。
限制
该技能面向基于 Tuist 的项目与 .strings 文件格式。资料未提供对其他构建系统、其他本地化格式(如 String Catalogs)的支持说明,也未提供具体收费、价格或平台信息。