Xcode .stringsdictファイル

Lingo.dev CLIによるXcode .stringsdictファイルのAI翻訳

Xcodeの.stringsdictファイルとは?

Xcodeの.stringsdictファイルは、iOSおよびmacOSアプリケーションにおける複数形ルールと可変文字列フォーマットを処理するためのApple形式です。これらはplist XML構造を使用して、数量やその他の変数に基づいて異なる文字列のバリエーションを定義します。

例えば:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>welcome_message</key>
	<dict>
		<key>NSStringLocalizedFormatKey</key>
		<string>Hello %#@user_count@!</string>
		<key>user_count</key>
		<dict>
			<key>NSStringFormatSpecTypeKey</key>
			<string>NSStringPluralRuleType</string>
			<key>NSStringFormatValueTypeKey</key>
			<string>d</string>
			<key>zero</key>
			<string>No users</string>
			<key>one</key>
			<string>1 user</string>
			<key>other</key>
			<string>%d users</string>
		</dict>
	</dict>
</dict>
</plist>

Lingo.dev CLIとは?

Lingo.dev CLIは、AIでアプリやコンテンツを翻訳するための無料のオープンソースCLIです。従来の翻訳管理ソフトウェアに代わるものとして設計されており、既存のパイプラインと統合できます。

詳細については、概要をご覧ください。

このガイドについて

このガイドでは、Lingo.dev CLIを使用してXcodeの.stringsdictファイルを翻訳する方法を説明します。

以下の方法を学びます:

  • ゼロからプロジェクトを作成する
  • 翻訳パイプラインを設定する
  • 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. ターゲットロケールの設定

_ターゲットロケール_とは、コンテンツを翻訳したい言語や地域のことです。ターゲットロケールを設定するには、i18n.jsonファイルのlocale.targetsプロパティを設定します:

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

ステップ4. ソースコンテンツの作成

まだ作成していない場合は、翻訳するコンテンツを含むXcode .stringsdictファイルを1つ以上作成します。これらのファイルは、パスのどこかにソースロケールを含むパスに配置する必要があります(例:ディレクトリ名としてen/や、ファイル名の一部としてmessages.en.stringsdictなど)。

ステップ5. バケットの作成

  1. i18n.jsonファイルのbucketsオブジェクトに"xcode-stringsdict"オブジェクトを追加します:

    {
      "$schema": "https://lingo.dev/schema/i18n.json",
      "version": "1.10",
      "locale": {
        "source": "en",
        "targets": ["es"]
      },
      "buckets": {
        "xcode-stringsdict": {}
      }
    }
    
  2. "xcode-stringsdict"オブジェクト内で、1つ以上のincludeパターンの配列を定義します:

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

    これらのパターンは、翻訳するファイルを定義します。

    パターン自体は:

    • 設定されたロケールのプレースホルダーとして[locale]を含む必要があります
    • ファイルパスを指定できます(例:"[locale]/Localizable.stringsdict"
    • ワイルドカードプレースホルダーとしてアスタリスクを使用できます(例:"[locale]/*.stringsdict"

    再帰的なグロブパターン(例:**/*.stringsdict)はサポートされていません。

ステップ6. LLMの設定

Lingo.dev CLIは、AIでコンテンツを翻訳するために大規模言語モデル(LLM)を使用します。これらのモデルを使用するには、サポートされているプロバイダーからAPIキーが必要です。

可能な限り早く始めるために、毎月10,000トークンの無料使用量を提供する当社独自のホスティングプラットフォームLingo.dev Engineの使用をお勧めします:

  1. Lingo.devアカウントにサインアップしてください。

  2. 次のコマンドを実行します:

    npx lingo.dev@latest login
    

    これによりデフォルトのブラウザが開き、認証を求められます。

  3. 画面の指示に従ってください。

ステップ 7. 翻訳を生成する

「i18n.json」ファイルが含まれるディレクトリで、次のコマンドを実行します:

npx lingo.dev@latest run

このコマンドは:

  1. i18n.jsonファイルを読み込みます。
  2. 翻訳が必要なファイルを見つけます。
  3. ファイルから翻訳可能なコンテンツを抽出します。
  4. 設定されたLLMを使用して抽出されたコンテンツを翻訳します。
  5. 翻訳されたコンテンツをファイルシステムに書き戻します。

翻訳が初めて生成されるとき、i18n.lockファイルが作成されます。このファイルは、どのコンテンツが翻訳されたかを追跡し、後続の実行で不要な再翻訳を防ぎます。

en/example.stringsdict

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>welcome_message</key>
	<dict>
		<key>NSStringLocalizedFormatKey</key>
		<string>Hello %#@user_count@!</string>
		<key>user_count</key>
		<dict>
			<key>NSStringFormatSpecTypeKey</key>
			<string>NSStringPluralRuleType</string>
			<key>NSStringFormatValueTypeKey</key>
			<string>d</string>
			<key>zero</key>
			<string>No users</string>
			<key>one</key>
			<string>1 user</string>
			<key>other</key>
			<string>%d users</string>
		</dict>
	</dict>
</dict>
</plist>

es/example.stringsdict

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>welcome_message</key>
	<dict>
		<key>NSStringLocalizedFormatKey</key>
		<string>¡Hola %#@user_count@!</string>
		<key>user_count</key>
		<dict>
			<key>NSStringFormatSpecTypeKey</key>
			<string>NSStringPluralRuleType</string>
			<key>NSStringFormatValueTypeKey</key>
			<string>d</string>
			<key>zero</key>
			<string>Sin usuarios</string>
			<key>one</key>
			<string>1 usuario</string>
			<key>other</key>
			<string>%d usuarios</string>
		</dict>
	</dict>
</dict>
</plist>

i18n.json

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

i18n.lock

version: 1
checksums:
  a96f640d0f744d993247e36ea1b33052:
    welcome_message/NSStringLocalizedFormatKey: f142738692c027d95dce521e7cb29c82
    welcome_message/user_count/NSStringFormatSpecTypeKey: 8cc03ef30ad5b2d8e27f3612627d932e
    welcome_message/user_count/NSStringFormatValueTypeKey: fe9efa39a6fd9f10358f43f00e0ab82b
    welcome_message/user_count/zero: 3d4643c483a49c2f61e17aaa8620e71e
    welcome_message/user_count/one: 3b547431ab12f0fba84307e6a81109d8
    welcome_message/user_count/other: cb01ae522c991a2ad651b4049339c48a
    notification_count/NSStringLocalizedFormatKey: e01fd796051132b678d7574a11e9a944
    notification_count/count/NSStringFormatSpecTypeKey: 8cc03ef30ad5b2d8e27f3612627d932e
    notification_count/count/NSStringFormatValueTypeKey: fe9efa39a6fd9f10358f43f00e0ab82b
    notification_count/count/zero: ac0137deebf6e2b972c6c714dd8658ee
    notification_count/count/other: 9b350a78e1c499b9ab69eb330162c8ee