Streamline your localized strings
Media & Web 进阶 20m

简化你的本地化字符串

Streamline your localized strings

2021年6月9日

在 Apple 官方观看视频

一句话判断

如果你还在手动维护 .strings.stringsdict 文件,赶紧迁移到 String Catalog——这是本地化工作流的一次性投资,之后全是收益。

这场 Session 讲了什么

Session 是对 “Localize your SwiftUI app” 的补充,重点讲字符串管理的工具链改进。核心是 String Catalog 的迁移流程和高级用法。

演示了如何从传统的 .strings + .stringsdict 文件迁移到 String Catalog。Xcode 13 提供了一键迁移工具:选中旧的本地化文件,右键 > Migrate to String Catalog,Xcode 自动合并所有语言和变体到 .xcstrings 格式。

还讲解了几个容易忽略的本地化细节:字符串中的格式化占位符(%lld%@)在不同语言中可能顺序不同;DateFormatterNumberFormatter 的本地化行为;以及如何处理右到左(RTL)语言中的布局翻转。

最后展示了在 CI 中自动导出本地化文件、导入翻译结果的工作流,以及如何用 xcodebuild -exportLocalizations 命令行工具实现全自动化。

值得深挖的点

占位符顺序问题的解法

"You have %lld messages from %@" 在英文中是先数字后名字,但在某些语言中可能需要反过来。String Catalog 允许你为每种语言指定不同的占位符位置,通过位置参数(%1$@%2$lld)实现。这个功能在传统 .strings 文件中就有,但 String Catalog 让它更直观——你在编辑器中能看到每个语言的实际效果。

自动检测未翻译的字符串

String Catalog 在编译时会检查所有本地化 key 是否都有每种语言的翻译。如果没有,Xcode 会显示警告。这解决了”上线后才发现某个按钮的文字没翻译”的问题。你可以设置”源语言”(通常是英文),只有非源语言的缺失才会报警。

代码片段

位置参数处理不同语言的占位符顺序

// 英文:"%1$@ sent you %2$lld messages"
// 日文:"%2$lld件のメッセージが%1$@から届きました"
// 注意参数顺序不同

// 在代码中使用:
String(localized: "\(senderName) sent you \(messageCount) messages")
// String Catalog 自动处理不同语言的参数位置

// 手动写法(不推荐,应该用 String Catalog):
String(format: NSLocalizedString("message.summary", comment: ""), 
       senderName, messageCount)

命令行导出和导入本地化

// 导出本地化文件
// xcodebuild -exportLocalizations \
//   -project MyApp.xcodeproj \
//   -localizationPath ./localizations \
//   -exportLanguage zh-Hans \
//   -exportLanguage ja

// 导入翻译结果
// xcodebuild -importLocalizations \
//   -project MyApp.xcodeproj \
//   -localizationPath ./localizations/zh-Hans.xcloc

// CI 中的自动化脚本:
// 1. 导出 -> 发给翻译 API -> 获取翻译 -> 导入

处理 RTL 语言的布局

// SwiftUI 自动处理 RTL 布局
HStack {
    Text("名称")   // 在 RTL 语言中自动右对齐
    Spacer()
    Text("值")     // 自动左对齐
}

// 需要翻转的图标
Image(systemName: "chevron.right")
    // 在 RTL 语言中自动翻转为 chevron.left
    .environment(\.layoutDirection, .leftToRight)  // 强制方向

// 检测当前布局方向
@Environment(\.layoutDirection) var layoutDirection
if layoutDirection == .rightToLeft {
    // RTL 特定的处理
}

最佳实践

迁移流程: 先在非主分支上跑迁移工具,确认 String Catalog 的内容完整后再合并。迁移后删除旧的 .strings 和 .stringsdict 文件,避免两套系统共存造成混乱。

翻译工作流: 把导出/导入本地化文件集成到 CI。每次代码合并到主分支时自动导出,翻译完成后自动导入。这保证了翻译始终和代码同步。

还有什么值得关注

  • String Catalog 支持为 App Extension 和 Framework 分别管理翻译。
  • Xcode 13 的 String Catalog 编辑器支持直接在表格中编辑翻译,不用打开 JSON。
  • Automatic Grammar Agreement 是新特性,能根据上下文自动调整语法一致性(如法语中的性别一致)。
WWDC 2021