|
文件扩展名 |
.xcstrings |
|
API 扩展 |
strings_catalog |
|
导入 |
是 |
|
导出 |
是 |
|
复数形式支持 |
是 |
|
描述支持 |
是 |
|
格式选项 这些选项可在文件上传和/或下载时指定。根据上传/下载方法(API、CLI、Repo sync 等),它们可以在查询参数 |
convert_placeholder default_extraction_state locale_code_mapping |
Apple Strings Catalog (.xcstrings) 是 Xcode 15 中引入的一种本地化格式。它通过支持用于处理复数、特定设备变体等的结构化格式,增强了开发人员管理本地化 Strings 的方式。这种格式正逐渐成为管理 iOS 和 macOS 应用程序本地化的推荐方法。
备注、extractionState 和 shouldTranslate 元数据字段会按要求的顺序导入和导出,以确保与 Xcode 的兼容性。
Phrase 也会在导入期间将 Xcode 译文状态映射到最接近的 Strings 等效项,并在导出时将其转换回 Xcode 兼容的值。如果无特定映射适用,则使用 translated 作为默认导出值。如有需要,请使用 选项以略过状态映射。
代码示例
{
"sourceLanguage": "en",
"strings": {
"Sync Warning": {
"comment": "Sync function unavailable message",
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Cloud Sync must be enabled to use this feature."
}
},
"fr": {
"stringUnit": {
"state": "translated",
"value": "La synchronisation cloud doit être activée pour utiliser cette fonction."
}
}
}
},
"Chosen Collections": {
"comment": "View title indicating selected photo collections",
"localizations": {
"fr": {
"variations": {
"plural": {
"one": {
"stringUnit": {
"state": "translated",
"value": "%ld collection sélectionnée"
}
},
"other": {
"stringUnit": {
"state": "translated",
"value": "%ld collections sélectionnées"
}
}
}
}
},
"en": {
"variations": {
"plural": {
"one": {
"stringUnit": {
"state": "translated",
"value": "%ld Collection Selected"
}
},
"other": {
"stringUnit": {
"state": "translated",
"value": "%ld Collections Selected"
}
}
}
}
}
}
},
"Settings Hub": {
"localizations": {
"es": {
"stringUnit": {
"state": "translated",
"value": "Centro de configuración"
}
}
}
}
},
"version": "1.0"
}
使用 Phrase CLI 时,文件导出遵循 .phrase.yml 配置文件中定义的结构。为确保在执行 pull 操作期间将多种语言导出到单个 .XCSTRINGS 文件中:
-
在 CLI 配置文件中仅指定一个文件译文。
-
使用
locale_ids参数列出导出中包含的所有语言区域。
Example .phrase.yml configuration
pull:
targets:
- file: ./i18n-test/Localizable.xcstrings
params:
locale_id: en # Main language for the download
locale_ids: # Additional languages to include
- de
- es
- fr
file_format: strings_catalog
设备类型
Apple Strings Catalog 支持设备类型,允许根据所使用的 Apple 设备为同一个键提供不同的译文内容。
为在 Phrase Strings 中处理设备类型,系统会使用分隔符 |==| 为每种设备创建单独的键。导入 .XCSTRINGS 文件时,设备类型会使用此分隔符添加到基础键名称中。
示例
applewatch 设备的键名 %lld Product(s) Ordered 将作为名为 %lld Product(s) Ordered|==|device.applewatch 的复数键导入到 Phrase Strings 中。
在导出期间,Phrase Strings 会使用分隔符检测设备变体,并为 Apple 的本地化格式恢复其原始嵌套结构。
{
"sourceLanguage": "en",
"strings": {
"%lld Product(s) Ordered": {
"comment": "Indicates the number of products ordered, with device-specific variations",
"localizations": {
"en": {
"variations": {
"device": {
"applewatch": {
"variations": {
"plural": {
"one": {
"stringUnit": {
"state": "translated",
"value": "%lld Product ordered (Apple Watch)"
}
},
"other": {
"stringUnit": {
"state": "translated",
"value": "%lld Products ordered (Apple Watch)"
}
}
}
}
},
"ipad": {
"variations": {
"plural": {
"one": {
"stringUnit": {
"state": "translated",
"value": "%lld Product ordered (iPad)"
}
},
"other": {
"stringUnit": {
"state": "translated",
"value": "%lld Products ordered (iPad)"
}
}
}
}
},
"iphone": {
"variations": {
"plural": {
"one": {
"stringUnit": {
"state": "translated",
"value": "%lld Product ordered (iPhone)"
}
},
"other": {
"stringUnit": {
"state": "translated",
"value": "%lld Products ordered (iPhone)"
}
}
}
}
},
"mac": {
"variations": {
"plural": {
"one": {
"stringUnit": {
"state": "translated",
"value": "%lld Product ordered (Mac)"
}
},
"other": {
"stringUnit": {
"state": "translated",
"value": "%lld Products ordered (Mac)"
}
}
}
}
}
}
}
},
"fr": {
"variations": {
"plural": {
"few": {
"stringUnit": {
"state": "translated",
"value": "%lld produit(s) commandé(s)"
}
},
"many": {
"stringUnit": {
"state": "translated",
"value": "%lld produits commandés"
}
},
"one": {
"stringUnit": {
"state": "translated",
"value": "%lld produit commandé"
}
}
}
}
}
}
}
}
}
字符串替换
Apple Strings Catalog 支持为动态内容提供灵活占位符的字符串替换。
为了在 Phrase Strings 中处理字符串替换,会使用分隔符 |==| 创建单独的键。导入 .XCSTRINGS 文件时,替换项会使用此分隔符添加到基础键名称中。
Phrase Strings 还支持直接在项目中创建替换字符串。手动创建替换结构时,必须定义基础键和相应的替换键,以确保在导出期间生成正确的嵌套格式。
替换始终需要特定的键命名格式:keyName|==|substitution.[specifier]。
示例:从现有 .XCSTRINGS 文件导入替换结构
名为 birdSightingAlert 的 BIRDS 替换键被导入为 Phrase Strings 中名为 birdSightingAlert|==|substitution.BIRDS 的复数键。
在导出期间,Phrase Strings 会使用分隔符检测替换,并为 Apple 的本地化格式恢复其原始嵌套结构。
"birdSightingAlert": {
"comment": "Alert message indicating the number of birds spotted",
"localizations": {
"en": {
"stringUnit": {
"state": "new",
"value": "You spotted %#@BIRDS@!"
},
"substitutions": {
"BIRDS": {
"formatSpecifier": "BIRDS",
"variations": {
"plural": {
"one": {
"stringUnit": {
"state": "new",
"value": "a bird"
}
},
"other": {
"stringUnit": {
"state": "new",
"value": "several birds"
}
},
"zero": {
"stringUnit": {
"state": "new",
"value": "no birds"
}
}
}
}
}
}
}
}
示例:从头开始创建替换字符串
-
基础键
名为
keyName的基础键表示包含替换占位符%#@format@的顶级格式字符串。导出时,此键被写入为该条目的主要
stringUnit:"keyName": { "localizations": { "en": { "stringUnit": { "state": "translated", "value": "%#@format@" } } } } -
替换键
替换字符串被定义为使用替换命名格式的独立键:
keyName|==|substitution.li。此键包含替换文本,通常带有复数变体。在导出期间,Phrase Strings 会使用
|==|substitution.分隔符检测替换,并恢复基础键下的相应嵌套结构:{ "sourceLanguage": "en", "strings": { "keyName": { "localizations": { "en": { "stringUnit": { "state": "translated", "value": "%#@format@" }, "substitutions": { "li": { "formatSpecifier": "li", "variations": { "plural": { "one": { "stringUnit": { "state": "translated", "value": "%@ day" } }, "other": { "stringUnit": { "state": "translated", "value": "%@ 天" } } } } } } } } } }, "version": "1.0" }
格式选项
|
标识符 |
convert_placeholder |
|
类型 |
布尔值 |
|
上传 |
否 |
|
下载 |
是 |
|
默认 |
false |
|
说明 |
占位符将转换为匹配格式的特定要求。示例: |
|
标识符 |
default_extraction_state |
|
类型 |
字符串 |
|
上传 |
否 |
|
下载 |
是 |
|
默认 |
null |
|
说明 |
定义当键上尚未定义提取状态时,写入导出文件中键的 支持:
|
|
标识符 |
locale_code_mapping |
|
类型 |
对象 |
|
上传 |
是 |
|
下载 |
是 |
|
默认 |
{} |
|
说明 |
将 Phrase 区域代码映射到写入 .XCSTRINGS 文件的区域代码。每个键都是 Phrase 区域代码;每个值都是写入文件的代码,例如: {
"en": "en-GB",
"fr": "fr-FR"
}
下载时,Phrase 会重写 上传时,Phrase 会反向应用相同的映射,并将文件区域代码转换回相应的 Phrase 区域代码,包括 此选项仅影响从 .XCSTRINGS 文件本身读取和写入的区域代码。基于文件名的区域映射(例如用于 Git 集成文件命名模式)是一个单独的设置,它映射的是文件路径,而不是 .XCSTRINGS 内部的代码。 |