支持文件类型 (Strings)

.XCSTRINGS - Apple Strings Catalog (Strings)

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

文件扩展名 

.xcstrings

API 扩展 

strings_catalog

导入 

导出 

复数形式支持 

描述支持 

格式选项

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

convert_placeholder

default_extraction_state

locale_code_mapping

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

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

Phrase 也会在导入期间将 Xcode 译文状态映射到最接近的 Strings 等效项,并在导出时将其转换回 Xcode 兼容的值。如果无特定映射适用,则使用 translated 作为默认导出值。如有需要,请使用 Ignore translation state on import 选项以略过状态映射。

代码示例

{
  "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 文件导入替换结构

名为 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 内部的代码。

这篇文章有帮助吗?

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.