用途:把应用从单一语言扩展到多语言并长期维持。资料基于一次 iOS 应用上线 36 种语言的实践,强调先对源语言做人性化改写再翻译,因为事后修改英文句子会导致每种语言都要重译。
主要能力与流程:用平台提取器生成键列表,而不是靠 grep 搜索引号字符串;分批机器翻译,并用校验器拒绝丢失格式说明符或复数类别的批次;在 RTL 语言和长词语言(德语、芬兰语)中实际运行查看。
类型规则:任何被人阅读的内容必须使用平台的可本地化类型,如 SwiftUI 的 LocalizedStringKey、React/Next 的 t("key")、Android Compose 的 stringResource(R.string.x),而不是普通 String 常量,否则提取器看不到、控件不翻译且英文界面看起来正常。建议在 pre-commit 钩子中加入针对 title、label、note 等命名且类型为普通字符串的 lint 规则。
易逃逸场景:枚举 rawValue.capitalized 不是标签;不要与显示文字比较(如 label == "Auto");无障碍标识符不是标题,需单独传递。
计数、日期与货币:计数名词走复数系统而非 == 1 三元表达式,CLDR 类别因语言而异(日语 1、英语 2、罗马尼亚语和希伯来语 3、俄语和波兰语 4、阿拉伯语 6),只有 other 是普遍必需。日期用模板构建,如 setLocalizedDateFormatFromTemplate、Intl.DateTimeFormat、DateTimeFormatter.ofLocalizedDate。固定格式需固定 locale,如 en_US_POSIX。时长和数字也应用格式化器。不要把年份插入可翻译字符串。缓存格式化器会保留创建时的语言,应每次使用重建或在变更时重建。
运行时切换:系统在代码运行前解析 bundle;覆盖必须覆盖所有查找路径;"System" 必须真正指系统,需先清除自有语言键再读取平台语言列表。启动时记录一行日志说明选择与解析结果。
机器翻译:适合作为默认发布方式,但法律或金钱字符串绝不机器翻译;记录哪些语言有母语者审校。每批校验格式说明符、复数类别、品牌名与单位、长度是否超限。
测试:测试套件应在固定语言下运行;断言针对构建后的 bundle;检查比英语复数形式更多的语言;截图最长语言和 RTL 语言;用平台方式切换 RTL。屏幕朗读内容交给平台时长格式化器。
商店页面:应用翻译不等于商店列表翻译,App Store 约 50 个 locale、Google Play 约 80 个,需有意决定填充哪些。翻译前核对源语言列表与代码;元数据保存在仓库中,如 asc metadata pull。关键词应在商店中调研而非翻译,注意复合词拆分、部分市场英文名应用排名靠前、部分市场本地词胜出。
交付物:完整目录及缺失报告脚本、校验批次的合并工具、类型错误的 lint 或钩子规则、说明语言集与添加方式的文档、至少一张 RTL 和一张长词语言截图。限制:资料未提供具体安装命令、收费或平台支持范围。