支持文件类型 (Strings)

.XCSTRINGS - Apple Strings Catalog (Strings)

文本由 Phrase Language AI 从英语机器翻译而得。

文件扩展名 

.xcstrings

API 扩展 

strings_catalog

导入 

导出 

复数形式支持 

描述支持 

格式选项

这些选项可在上传和/或下载文件时指定。根据上传/下载方法(API、CLI、Repo 同步等),它们可以在查询参数 上传下载<3> 或 phrase.yml<5> 配置文件中指定。

convert_placeholder

default_extraction_state

locale_code_mapping

Apple Strings Catalog<1> (.xcstrings) 是 Xcode 15 中引入的一种本地化格式。它通过支持用于处理复数、特定设备变体等的结构化格式,增强了开发人员管理本地化 Strings 的方式。这种格式正成为管理 iOS 和 macOS 应用程序本地化的推荐方法。

备注extractionState<2> 和 shouldTranslate<3> 元数据字段会按要求的顺序导入和导出,以确保与 Xcode 的兼容性。

Phrase 也会在导入期间将 Xcode 译文状态映射到最接近的 Strings 等效项,并在导出时将其转换回与 Xcode 兼容的值。如果没有任何特定的映射适用,则使用 已翻译<1> 作为默认导出值。如有需要,请使用 导入时略过译文状态 选项以跳过状态映射。

代码示例

{
  "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<1> 时,文件导出遵循 .phrase.yml<2> 配置文件中定义的结构。为确保在拉取操作期间将多种语言导出到单个 .XCSTRINGS 文件中:

  • 在 CLI 配置文件中仅指定一个译文目标。

  • 使用 locale_ids<1> 参数列出导出中包含的所有语言区域。

.phrase.yml<3> 配置示例

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

<1>设备变体

Apple Strings Catalog 支持设备变体,允许根据所使用的 Apple 设备为同一个键提供不同的译文内容。

为了在 Phrase Strings 中处理设备变体,系统会使用分隔符 |==|<1> 为每种设备创建单独的键。导入 .XCSTRINGS 文件时,设备类型会使用此分隔符添加到基础键名中。

示例

名为 %lld Product(s) Ordered<1> 且针对 applewatch<2> 设备的键,在导入 Phrase Strings 时会作为名为 %lld Product(s) Ordered|==|device.applewatch<3> 的复数键。

在导出期间,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 文件导入替换结构

名为 birdSightingAlertBIRDS 替换键被导入为 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

说明 

占位符将被转换为匹配格式的特定要求。示例:$s$@, %s%@

标识符 

default_extraction_state

类型 

字符串

上传 

下载 

默认 

null

说明 

定义当键上尚未定义提取状态时,写入导出文件中键的 extractionState 值。如果键已包含 extractionState,则其值在导出期间会被保留。

支持:

  • UI 下载

  • API

  • CLI(通过 .phrase.yml 配置)和 Repo Sync

标识符 

locale_code_mapping

类型 

对象

上传 

下载 

默认 

{}

说明 

将 Phrase 区域代码映射到写入 .XCSTRINGS 文件的区域代码。每个键都是 Phrase 区域代码;每个值都是写入文件的代码,例如:

{
  "en": "en-GB",
  "fr": "fr-FR"
}

下载时,Phrase 会重写 sourceLanguage 字段以及任何与映射键匹配的 localizations 键,并将其替换为映射值。没有映射的代码保持不变。

上传时,Phrase 会反向应用相同的映射,并将文件区域代码转换回相应的 Phrase 区域代码,包括 sourceLanguage

此选项仅影响从 .XCSTRINGS 文件本身读取和写入的区域代码。基于文件名的区域映射(例如用于 Git 集成文件命名模式)是一个单独的设置,它映射的是文件路径,而不是 .XCSTRINGS 内部的代码。

从 iOS Strings (.strings) 迁移到 Strings Catalog (.xcstrings)

原 iOS Strings 格式 (.strings) 将翻译内容中的字面反斜杠-n 序列 (\\n) 视为等同于实际的换行符。因此,在使用 .strings 格式时创建或编辑的翻译可能包含字面文本 \\n,而不是实际的换行符。

Strings Catalog (.xcstrings) 是一种基于 JSON 的格式。当包含字面量 \n 序列的内容导出到 .xcstrings 时,JSON 编码会将该字面量文本在文件中转义为 \\n。此行为并非双重转义错误。它反映了翻译内容中已存在的字面量 \n 文本,并使用正确的 JSON 转义进行了导出。

若要在从 .strings 迁移到 .xcstrings 后解决此问题,请将受影响内容中的字面量 \n 序列替换为实际换行符:

  1. 照常导出内容。

  2. 在文本编辑器中打开导出的文件。

  3. 将所有字面量 \n 序列实例替换为实际换行符。

  4. 重新导入文件。

应用内搜索和替换不支持插入实际换行符,因此必须在重新导入文件之前在外部文本编辑器中执行此替换。

这篇文章有帮助吗?

Sorry about that! In what way was it not helpful?

The article didn’t address my problem.
I couldn’t understand the article.
The feature doesn’t do what I need.
Other reason.

Note that feedback is provided anonymously so we aren't able to reply to questions.
If you'd like to ask a question, submit a request to our Support team.
Thank you for your feedback.