Xcode .strings 文件

使用 Lingo.dev CLI 对 Xcode .strings 文件进行 AI 翻译

什么是 Xcode .strings 文件?

Xcode .strings 文件是 Apple 用于在 iOS 和 macOS 应用中存储本地化文本的格式。它采用简单的键值对格式,并支持注释和特殊字符。

例如:

/* Basic examples */
"welcome_message" = "Hello, world!";
"login_button" = "Log In";
"error_message" = "Something went wrong";

/* Escaped characters */
"quote_example" = "She said \"Hello world!\"";
"newline_example" = "First line\nSecond line";

/* Unicode and special characters */
"unicode_example" = "Hello 世界 🌍";
"emoji" = "👋 Hello! 🎉";

什么是 Lingo.dev CLI?

Lingo.dev CLI 是一个免费的开源命令行工具,可通过 AI 翻译应用和内容。它旨在替代传统的翻译管理软件,并可集成到现有的开发流水线中。

如需了解更多信息,请参见 概述

关于本指南

本指南介绍如何使用 Lingo.dev CLI 翻译 Xcode .strings 文件。

你将学习如何:

  • 从零创建项目
  • 配置翻译流水线
  • 使用 AI 生成翻译

前置条件

要使用 Lingo.dev CLI,请确保已安装 Node.js v18 及以上版本:

❯ node -v
v22.17.0

步骤 1. 创建项目

在你的项目目录下,创建一个 i18n.json 文件:

{
  "$schema": "https://lingo.dev/schema/i18n.json",
  "version": "1.10",
  "locale": {
    "source": "en",
    "targets": ["es"]
  },
  "buckets": {}
}

该文件定义了翻译流水线的行为,包括需要翻译的语言以及本地化内容在文件系统中的位置。

如需了解可用属性,请参见 i18n.json

步骤 2. 配置源语言环境

源语言环境 是指你的内容最初编写时所用的语言和地区。要配置源语言环境,请在 i18n.json 文件中设置 locale.source 属性:

{
  "$schema": "https://lingo.dev/schema/i18n.json",
  "version": "1.10",
  "locale": {
    "source": "en",
    "targets": ["es"]
  },
  "buckets": {}
}

源语言环境必须以 BCP 47 语言标签 的形式提供。

有关 Lingo.dev CLI 支持的所有语言环境代码的完整列表,请参见 支持的语言环境代码

第 3 步:配置目标语言环境

目标语言环境 是指您希望将内容翻译成的语言和地区。要配置目标语言环境,请在 locale.targets 属性中设置,并写入 i18n.json 文件:

{
  "$schema": "https://lingo.dev/schema/i18n.json",
  "version": "1.10",
  "locale": {
    "source": "en",
    "targets": ["es"]
  },
  "buckets": {}
}

第 4 步:创建源内容

如果尚未创建,请新建一个或多个 Xcode .strings 文件,用于存放待翻译内容。这些文件的路径中必须包含源语言环境(例如,作为目录名 en/,或作为文件名的一部分 messages.en.strings)。

第 5 步:创建 bucket

  1. i18n.json 文件中,向 buckets 对象添加一个 "xcode-strings" 对象:

    {
      "$schema": "https://lingo.dev/schema/i18n.json",
      "version": "1.10",
      "locale": {
        "source": "en",
        "targets": ["es"]
      },
      "buckets": {
        "xcode-strings": {}
      }
    }
    
  2. "xcode-strings" 对象中,定义一个或多个 include 模式的数组:

    {
      "$schema": "https://lingo.dev/schema/i18n.json",
      "version": "1.10",
      "locale": {
        "source": "en",
        "targets": ["es"]
      },
      "buckets": {
        "xcode-strings": {
          "include": ["./[locale]/example.strings"]
        }
      }
    }
    

    这些模式用于定义需要翻译的文件。

    模式要求如下:

    • 必须包含 [locale] 作为已配置语言环境的占位符
    • 可以指向文件路径(如 "[locale]/Localizable.strings"
    • 可以使用星号作为通配符(如 "[locale]/*.strings"

    不支持递归 glob 模式(如 **/*.strings)。

第 6 步:配置 LLM

Lingo.dev CLI 使用大型语言模型(LLM)通过 AI 翻译内容。要使用这些模型,您需要从支持的服务商获取 API 密钥。

为了尽快开始使用,我们推荐选择 Lingo.dev Engine —— 我们自有的托管平台,每月可免费使用 10,000 个 token:

  1. 注册 Lingo.dev 账号

  2. 运行以下命令:

    npx lingo.dev@latest login
    

这将会打开您的默认浏览器,并要求您进行身份验证。

  1. 按照提示操作。

步骤 7. 生成翻译内容

在包含 i18n.json 文件的目录下,运行以下命令:

npx lingo.dev@latest run

该命令将:

  1. 读取 i18n.json 文件。
  2. 查找需要翻译的文件。
  3. 提取文件中的可翻译内容。
  4. 使用已配置的 LLM 翻译提取的内容。
  5. 将翻译后的内容写回文件系统。

首次生成翻译时,会创建一个 i18n.lock 文件。该文件用于记录已翻译的内容,防止后续运行时重复翻译。

示例

en/example.strings

/* Basic examples */
"welcome_message" = "Hello, world!";
"login_button" = "Log In";
"error_message" = "Something went wrong";

"user_profile_title" = "User Profile";

/* Escaped characters */
"quote_example" = "She said \"Hello world!\"";
"newline_example" = "First line\nSecond line";

/* Unicode and special characters */
"unicode_example" = "Hello 世界 🌍";
"emoji" = "👋 Hello! 🎉";
"accents" = "Café, naïve, résumé";

/* Valid entries */
"settings_title" = "Settings";
"save_button" = "Save";

es/example.strings

/* Basic examples */
"welcome_message" = "¡Hola, mundo!";
"login_button" = "Iniciar Sesión";
"error_message" = "Algo salió mal";

"user_profile_title" = "Perfil de Usuario";

/* Escaped characters */
"quote_example" = "Ella dijo \"Hola mundo!\"";
"newline_example" = "Primera línea\nSegunda línea";

/* Unicode and special characters */
"unicode_example" = "Hola 世界 🌍";
"emoji" = "👋 ¡Hola! 🎉";
"accents" = "Café, naïve, résumé";

/* Valid entries */
"settings_title" = "Configuración";
"save_button" = "Guardar";

i18n.json

{
  "version": "1.10",
  "locale": {
    "source": "en",
    "targets": ["es"]
  },
  "buckets": {
    "xcode-strings": {
      "include": ["./[locale]/example.strings"]
    }
  },
  "$schema": "https://lingo.dev/schema/i18n.json"
}

i18n.lock

version: 1
checksums:
  c0001027bc43a90fe59344ea57847e7a:
    welcome_message: 0468579ef2fbc83c9d520c2f2f1c5059
    login_button: 0029e5a35676c0051e761fcd046ef9ee
    error_message: a3cd2f01c073f1f5ff436d4b132d39cf
    user_profile_title: bee775ff7216747b2111e93cefa57ddc
    quote_example: c519c83fe2629c0e9a6e7a14f64b6317
    newline_example: ae9313a2231a16f17e2367a4e5b322ee
    backslash_example: acf69a7273edf9f932f66027f699bbbe
    mixed_escapes: 9285b600baf307f7c060e20dc5778fad
    tab_example: 1451b8323511459dac68316a2594bb82
    multiline_literal: a4c5d1c388a06e29d96833e4d2f14a26
    multiline_mixed: f5d741606567d78281bc455074eb8f6c
    multiline_with_quotes: c82ec05ec488644808917b9c958da8cc
    after_comment: b7c19db10622cb67d4dd28270e85a428
    after_multiline_comment: 759d0ffce80451996a5a45b33a0870cc
    long_value: a54e8485e571c671e35865ba72cbcaf5
    unicode_example: 2de42b1aef6d20b314928b9c2554759d
    emoji: 1b387c2b5ce6c2cd608081ebcb5e6a94
    accents: 8c054e17f9b960d9317ca110a6fedf8c
    spaces_only: 8af60e2ee58a2e1e42071066e9c225da
    many_quotes: e2ff57b8058ab2c03c5b07cf901a7a48
    missing_semicolon: b2b5f0c3f552a348188de51bd4fcf511
    settings_title: 8df6777277469c1fd88cc18dde2f1cc3
    save_button: f7a2929f33bc420195e59ac5a8bcd454