要完成 Mac 应用中带复数形式的标签,请在 Xcode 中添加复数变体,为每种受支持的本地化提供所需的全部类别,并测试渲染结果。本指南使用一条虚构的项目选择提示。
任务是完成 SwiftUI Mac 应用中一个依赖数量的标签。这条消息报告所选项目的数量,接受非负整数,并在不同译文中保持相同含义。此工作流程结合类别覆盖、占位符检查和运行时测试,为已填写的目录条目设定明确的验收标准。
完整的复数覆盖需要满足什么条件?
Apple 建议在 Xcode 15 及更高版本中使用字符串目录进行复数本地化。其复数文档区分了必需的回退项与语法完整性:other 在字符串字典中是必需的,但省略其他特定语言的类别可能会导致语法错误。英语需要 one 和 other;其 zero 类别为可选。本地化包含复数形式的字符串。
可能的类别名称包括 zero、one、two、few、many 和 other。它们表示因语言而异的语法分组,而不是所有语言通用的六个数值范围。名为 one 的类别不应变成应用程序的通用规则,也不应只检查数量是否等于 1。Unicode 根据数字在短语中需要引起的变化定义这些类别,其中包括名词本身以外的变化。复数规则。
对于此任务,请使用以下消息约定。这些是示例应用的说明性要求,并非 Apple 规定的要求。
| 约定字段 | 本示例的要求 |
|---|---|
| 消息键 | selection.count |
| 英语默认值 | \(count) items selected |
| 输入 | 名为 count 的非负 Swift Int |
| 含义 | 当前选中的项目数量 |
| 输出 | 一条包含数量的完整本地化标签 |
| 覆盖范围 | 所有受支持的本地化,包括源本地化 |
| 验收标准 | 提供必需类别、保留数值替换,并检查有代表性的输出 |
要求数字出现在标签中,是对此标签特意作出的选择。Apple 允许复数变体拼出数字,或省略数字格式说明符。不同的消息约定可以允许这种做法。这里让数量始终可见,便于将标签与其描述的选择结果进行比较。本地化包含复数形式的字符串。
将 Swift 消息与目录关联
Swift 的 String.LocalizationValue 支持含有运行时插值的可本地化文本。当稳定标识符需要与英语源文本不同时,Apple 建议使用带独立 defaultValue 的 String 初始化器。这适用于 selection.count:标识符用于命名消息,默认值则提供英语措辞。String.LocalizationValue。
对于小型测试应用,请在 Xcode 15 或更高版本中创建一个使用 SwiftUI 的 macOS 应用项目,并将 macOS 部署目标设为 12 或更高版本。用下面的完整程序替换生成的应用入口文件;目标中只保留一个 @main 声明。在执行目录操作步骤之前,将 Localizable.xcstrings 添加到应用目标中。此程序需要 Xcode 和 macOS SDK;本研究环境中未对其进行编译。
import Foundation
import SwiftUI
@main
struct PluralSampleApp: App {
var body: some Scene {
WindowGroup {
PluralSampleView()
}
}
}
struct PluralSampleView: View {
@State private var count: Int = 1
private let samples: [Int] = [
0, 1, 2, 3, 4, 5, 10, 11, 12,
20, 21, 22, 100, 101, 102, 1_000_000
]
private var selectionLabel: String {
String(
localized: "selection.count",
defaultValue: "\(count) items selected",
comment: "Selection summary. The integer is the number of selected items. Keep the count visible in every plural variant."
)
}
var body: some View {
VStack(alignment: .leading, spacing: 16) {
Picker("Sample count", selection: $count) {
ForEach(samples, id: \.self) { value in
Text(verbatim: String(value)).tag(value)
}
}
Text(verbatim: selectionLabel)
}
.padding(24)
.frame(minWidth: 360)
}
}
数字选择器中的条目是测试输入。本地化摘要通过 String(localized:defaultValue:comment:) 解析,然后显示生成的字符串。Apple 说明,初始化器的第一个参数提供查找键,默认值提供源文本,注释则提供翻译上下文。Xcode 会在构建时提取通过可本地化 API 传入的字符串。为应用文本做好翻译准备。
将整数保留在可本地化插值中。对于此约定,不要在应用程序分支中预先拼出独立的英语单数和复数句子。使用一条消息,可以让目录承担清晰的职责:根据传入的数量选择合适的本地化措辞。
为每种受支持的本地化提供类别
使用 Xcode 编辑器创建变体结构:
- 选择
Product > Build以填充目录。 - 打开
Localizable.xcstrings并选择源本地化。 - 按住 Control 键并点按
selection.count,然后选择Vary by Plural。 - 填写每个源语言变体。
- 使用侧边栏中的
Add按钮添加受支持的本地化,然后填写其变体。
Xcode 会添加特定语言的复数形式,并确定插值所用的格式说明符。对源本地化应用复数变体,可让各语言间的变体结构保持同步;只对其他本地化应用此设置,则只会影响该本地化。使用字符串目录本地化和变体文本。
对于这个整数插值,英语条目可以是:
| 英语类别 | 目录值 |
|---|---|
one |
%lld item selected |
other |
%lld items selected |
实际插值类型应使用 Xcode 生成的说明符。Apple 文档中的整数示例使用 %lld;将其他占位符复制到译文中可能会破坏参数约定。Xcode 最初会用键的值预填变体字段,因此请检查每个字段中的措辞。使用字符串目录本地化和变体文本。
创建一份覆盖检查表,为每个实际的本地化标识符各设一行。记录 Xcode 为此消息生成的类别、每个类别的文本是否已完成,以及要测试哪些输入。使用项目中的真实标识符,可避免宽泛的语言标签掩盖尚未审核的本地化。
不要将英语类别集复制到每一行。同样,也不要要求所有地方都提供六个类别。让目录提供基础结构,然后在选择测试输入时查阅相应语言的基数复数规则。基数规则涉及数量;序数规则涉及位置,两者回答的是不同问题。Unicode 将它们列为不同的规则类型。Unicode 技术标准 #35:数字。
分别验证结构、占位符和渲染文本
使用三项检查,因为它们分别回答不同的问题。缺少类别属于覆盖问题;占位符错误属于格式问题;句子读起来别扭则属于措辞问题。分别记录这些问题,便能明确下一步要改什么。
检查类别覆盖
对于检查表中的每一行,将预期类别与目录中已填写的条目进行比较。确认存在 other,并确认没有预期类别的值为空,或仍是尚未处理的源文本副本。
要进行简单的完整性检查,可将预期集合定义为该本地化生成的类别,加上任何有意支持的覆盖项。缺失集合即为预期集合中减去已填写完成文本的类别。任何缺失项都意味着消息未达到本文的验收标准。这是一种根据文档中的变体工作流程制定的实用审核方法,并非声称 Xcode 会强制执行这份确切的检查表。
如果两个类别的措辞本就相同,请在需要的地方保留相同措辞,并分别审核这两个条目。目标是让消息在所有必需类别中都保留原意;不需要确保每一对字符串在视觉上都不同。
检查数值替换
构建项目并检查目录诊断信息。Apple 记录了字符串目录对常见问题的验证,例如格式说明符不匹配。解决这些诊断信息后,检查每个变体是否仍符合此消息必须显示数量的要求。构建支持多语言的应用。
对于这个只有一个参数的示例,请确认数值占位符存在、仍为数值类型,并且已在预期位置插入一次。构建成功是有用的证据,但验收决策还需要考虑类别覆盖和实际渲染文本。
在 Mac 应用中测试有代表性的数量
选择 Product > Scheme > Edit Scheme,选中 Run,然后打开 Options。设置 App Language 和相应的 App Region,关闭对话框并运行 Mac 应用。对每种受支持的本地化重复此操作。Apple 记录了这种通过 scheme 测试本地化输出的流程。运行应用时测试本地化。
示例选择器提供的是一组起始数量,并不代表普遍适用的类别覆盖。将适合每种本地化的数值加入其中,再将其测试行标记为完成。
| 测试选择 | 检查内容 |
|---|---|
0、1 和 2 |
空选择、选择一个项目和选择多个项目的情况 |
| 每个必需类别至少一个有代表性的输入 | 覆盖该本地化的语法区别 |
| 相关规则边界两侧的数值 | 数量增大时发生的类别变化 |
| 较大的有效数量 | 数值替换和可用标签空间 |
| 每个经过测试的输入 | 含义、完整措辞和可见数量 |
Unicode 规则将类别与条件和示例值关联起来;包括小数位数在内的数值细节可能会产生影响。此约定只接受整数。如果应用以后接受小数数量,应同时修改插值、源文本和测试,不要假定整数测试结果仍足以证明覆盖完整。Unicode 技术标准 #35:数字。
诊断意外结果
根据观察到的现象选择下一步检查:
| 现象 | 下一步操作 |
|---|---|
目录中缺少 selection.count |
重新构建,并检查可本地化调用和所选表格 |
| 只有一种本地化有复数变体 | 重新检查应用 Vary by Plural 的位置 |
| 某个变体仍带有英语复数措辞 | 检查预填字段,并提供完成的译文 |
| 显示的数字缺失或格式错误 | 将该变体的占位符与 Xcode 生成的说明符及消息约定进行比较 |
| 数量较大时措辞异常 | 检查该本地化的类别规则,并添加有代表性的测试 |
| 正确的措辞无法完整显示 | 调整视图,并重新测试完整标签 |
对于使用 Xcode 15 之前版本的旧项目,Apple 支持的方式是使用 .strings 和 .stringsdict 资源。复数字典提供特定语言的变体,并要求 other;但这并不免除提供其余必需类别以确保语法正确的需要。本地化包含复数形式的字符串。
当每种受支持的本地化都有完整的覆盖检查表、占位符符合约定,并且有代表性的数量在运行中的应用里显示出预期标签时,这条消息就算完成。每当受支持的本地化、数值输入类型或消息含义发生变化时,都应重新检查这些条目。
来源
- 使用字符串目录本地化和变体文本 — Apple
- 本地化包含复数形式的字符串 — Apple
- String.LocalizationValue — Apple
- 为应用文本做好翻译准备 — Apple
- 运行应用时测试本地化 — Apple
- 构建支持多语言的应用 — Apple
- 复数规则 — Unicode 联盟
- Unicode 技术标准 #35:Unicode 通用区域设置数据仓库与规则 (CLDR),第 3 部分:数字 — Unicode 联盟