要完成 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 编辑器创建变体结构:

  1. 选择 Product > Build 以填充目录。
  2. 打开 Localizable.xcstrings 并选择源本地化。
  3. 按住 Control 键并点按 selection.count,然后选择 Vary by Plural。
  4. 填写每个源语言变体。
  5. 使用侧边栏中的 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;但这并不免除提供其余必需类别以确保语法正确的需要。本地化包含复数形式的字符串。

当每种受支持的本地化都有完整的覆盖检查表、占位符符合约定,并且有代表性的数量在运行中的应用里显示出预期标签时,这条消息就算完成。每当受支持的本地化、数值输入类型或消息含义发生变化时,都应重新检查这些条目。

来源