
Claude Code の Agent Skills で iOS アプリの多言語対応を自動化する(xcstrings → XLIFF → AI翻訳)
前回、「iOSアプリのローカライズ:.xcstrings を言語ごとの XLIFF ファイルに分割・結合する」を書いた。
XLIFF ベースのワークフローにより、.xcstrings を言語ごとに分割して AI 翻訳に渡せるようになった。しかし実際に運用してみると、エクスポート → 翻訳 → インポートの一連の手順を毎回手動で実行する作業が、対応言語の増加とともに大きなボトルネックになっていた。
そこで、Claude Code の Agent Skills を使ってこのワークフロー全体を自動化することにした。
xcstrings → エクスポート → AI翻訳 → インポート → xcstrings
本記事では、エクスポートからインポートまでを Claude Code に任せるスキルの設計と使い方を紹介する。
検証環境
- MacBook Pro (16インチ, 2023), Apple M2 Pro
- macOS 15.7.3
- Xcode 26.1.1
- Claude Code v2.1.77
Agent Skills とは
Agent Skills は、Claude Code に特定のタスクの処理方法を教える指示書のセットだ。SKILL.md というマークダウンファイルと、必要に応じて参照ファイルやスクリプトをフォルダにまとめ、~/.claude/skills/ に配置すると使えるようになる。私は「複数回同じプロンプトを入力しているな」と思ったタイミングでスキルを作成するようにしている。
スラッシュコマンド(/xcstrings-localize)で明示的に起動することも、「ローカライズして」のような自然言語で自動的にトリガーすることもできる。
特徴的なのは、ファイル読み込みを遅延できる点だ。Claude Code は起動時にフロントマター(スキル名と説明)だけを読み込み、スキルが実際にトリガーされた時点で初めて本文や参照ファイルをロードする。スキルをいくつ登録しても、使わないスキルがコンテキストを消費することはない。
Agent Skills の詳細は公式ドキュメントを参照してほしい。
作成したスキル
iOS アプリの多言語対応を自動化する xcstrings-localize というスキルを作成した。GitHub リポジトリで公開している。
ディレクトリ構成は以下の通りだ。
xcstrings-localize/
├── SKILL.md # ワークフロー指示書
└── references/
├── glossary.yaml # 翻訳しない固有名詞・統一用語の定義
└── language-guide.yaml # 言語別の複数形カテゴリ・敬語レベル・注意事項
3ファイルだけのシンプルな構成だ。それぞれの役割を解説していく。
SKILL.md の設計ポイント
フロントマター
SKILL.md の冒頭にある YAML フロントマターは、Claude Code がスキルを自動起動するかどうかの判断材料になる。
---
name: xcstrings-localize
description: >
iOS アプリの xcstrings (String Catalog) を起点としたローカライズスキル。
xcodebuild でエクスポートした xcloc パッケージ内の XLIFF を解析し、
未翻訳の trans-unit を対象言語に翻訳してインポート可能な状態にする。
プロジェクトが対応する全言語を自動検出して翻訳する。
ユーザーが「ローカライズ」「翻訳」「多言語対応」「xcstrings」「XLIFF」
「xcloc」「○○語対応」に言及した場合に使用する。
---
name フィールドがスラッシュコマンド名になる。/xcstrings-localize で明示的に起動できる。
description は、Claude Code が「このスキルを使うべきか?」を判断するための情報だ。ここに書いたキーワードに反応して自動起動するため、ユーザーが使いそうな表現を網羅的に含めている。「ローカライズ」「翻訳」「多言語対応」「xcstrings」「○○語対応」など、開発中に口にしそうな言葉を意識した。
公式ドキュメントでは、Claude はスキルをトリガーし損ねる傾向があるため description を「少し強めに書く」ことが推奨されている。個人的には言葉によるトリガーは期待できないので、毎回スラッシュコマンドを利用している。
翻訳対象の言語をハードコードしない
このスキルでは、翻訳対象の言語をハードコードしていない。
SKILL.md 内の「ステップ 0: 対象言語の特定」で、プロジェクトの .xcstrings ファイルを JSON パースして対応言語を自動取得するよう指示している。.xcstrings ファイルは JSON 形式なので、sourceLanguage(開発言語)以外のキーを抽出すれば翻訳対象の言語一覧が得られる。
この設計により、プロジェクト側で Xcode の String Catalog に新しい言語を追加するだけで、スキルが自動的にその言語も翻訳対象に含める。フランス語やイタリア語を後から追加しても、スキル側の修正は不要だ。
もちろん「英語だけ翻訳して」のようにユーザーが明示した場合は、指定された言語のみを対象にする。
XLIFF を壊さないための翻訳ルール
AI に XLIFF ファイルを編集させる上で、壊してはいけないものを明確にしておく必要がある。SKILL.md では以下のルールを「絶対に守るべきルール」として定義している。
1. **`<source>` 要素を変更しない** — Xcode はインポート時に source でマッチングする
2. **`id` 属性・`original` 属性を変更しない**
3. **フォーマット指定子を正確に保持する**:%@, %d, %lld, %1$@, %2$@
4. **stringsdict の変数キーをそのまま保持する**:%#@variable@
5. **翻訳した `<target>` に `state="translated"` を設定する**
6. **`xml:space="preserve"` を維持する**
特に重要なのは 1 と 3 だ。
<source> 要素を変更してしまうと、xcodebuild -importLocalizations でインポートした際にキーのマッチングに失敗し、翻訳がサイレントにスキップされる。エラーも出ずに無視されるため、気づきにくいバグの原因になる。
フォーマット指定子(%@、%d、%1$@ 等)は、翻訳文にそのまま含める必要がある。AI 翻訳で最も起きやすいミスの一つが、プレースホルダーの破損や脱落だ。%@ を %s に変えてしまったり、位置指定子のインデックスを変えてしまうケースがあるため、ルールとして明示している。
references/ ディレクトリで情報を分離する
用語集(glossary.yaml)と言語別ガイド(language-guide.yaml)を references/ ディレクトリに分離している。
SKILL.md 本文に全情報を詰め込むこともできるが、references/ に分けておくと、スキル起動時には必要な情報だけがロードされる。用語集が大きくなっても、翻訳ステップで実際に参照されるまでコンテキストを消費しない。
また、ファイルを分けることで、用語集だけをプロジェクトごとにカスタマイズするといった運用もしやすくなる。
用語集と言語ガイド
glossary.yaml(用語集)
glossary.yaml は、翻訳しない固有名詞のリストと、言語別に統一すべき訳語を定義する。
do_not_translate:
- HealthTakeout # アプリ名
- HealthKit
- Apple Watch
- CSV
- JSON
terminology:
エクスポート:
en: Export
zh-Hans: 导出
ko: 내보내기
fr: Exporter
it: Esportare
# 必要な言語コードを自由に追加
do_not_translate リストにより、アプリ名やプラットフォーム固有名詞が誤って翻訳されることを防ぐ。
terminology は言語コードをキーとして訳語を定義する。新しい言語に対応する場合は、キーを追加するだけだ。glossary.yaml に定義のない言語が翻訳対象になった場合、Claude は既存の訳語パターンと文脈から適切に翻訳する。
language-guide.yaml(言語別ガイド)
language-guide.yaml は、各言語の CLDR 複数形カテゴリ、敬語レベル、テキスト長の傾向、特記事項を定義する。
たとえばフランス語とアラビア語では、必要な複数形カテゴリが大きく異なる。
languages:
fr:
name: Français
plural_categories: [one, many, other]
formality: vouvoiement(vous)を基本とする
text_length: 日本語・英語より 15-20% 長くなる傾向
notes:
- UI ラベルは不定詞形を使用 (e.g., "Exporter", "Enregistrer")
- アクセント記号を正確に使用(é, è, ê, ë, à, ç 等)
ar:
name: العربية
plural_categories: [zero, one, two, few, many, other]
formality: فصحى(正則アラビア語)を基本とする
notes:
- RTL(右から左)レイアウト
- 6つの複数形カテゴリすべてを正確に翻訳すること
フランス語は one, many, other の3カテゴリだが、アラビア語は zero から other まで6カテゴリすべてが必要だ。日本語(other のみ)や英語(one, other)とは大きく異なるため、この情報がないと複数形の翻訳漏れが発生する。
現在14言語分のガイドを収録している。未掲載の言語が対象になった場合は、CLDR の複数形ルールを参照するよう SKILL.md 内で指示している。
セットアップ
スキルの導入はリポジトリをクローンしてシンボリックリンクを張るだけだ。
# リポジトリをクローン
git clone https://github.com/CH3COOH/claude-skills.git ~/repos/claude-skills
# ~/.claude/skills/ にシンボリックリンクを作成
mkdir -p ~/.claude/skills
ln -s ~/repos/claude-skills/xcstrings-localize ~/.claude/skills/xcstrings-localize
シンボリックリンク方式にしているので、スキルの更新は git pull だけで完了する。
cd ~/repos/claude-skills && git pull
セットアップ後、必要に応じて glossary.yaml の do_not_translate リストと terminology をプロジェクトに合わせてカスタマイズするとよい。アプリ名やプロジェクト固有の用語を追加しておくと、翻訳の一貫性が向上する。
実行デモ
実際にプロジェクトでスキルを実行してみる。
XcodeのString Catalogエディタで見た状態はこのようになっている。対応する文字列リソースが空の状態だ。

スキルの起動
Claude Code で以下のいずれかの方法でスキルを起動する。
/xcstrings-localize
または、自然言語で話しかける。
ローカライズして
英語とフランス語に翻訳して
ここでは確実にスキルを起動するため、スラッシュコマンドで /xcstrings-localize を実行する。

言語の自動検出
スキルが起動すると、まずプロジェクト内の .xcstrings ファイルから対応言語を自動検出する。

エクスポート
検出された言語に対して xcodebuild -exportLocalizations が実行され、言語ごとの xcloc パッケージが生成される。

AI 翻訳
各言語の XLIFF ファイル内で state="new"(未翻訳)の <trans-unit> が特定され、翻訳が実行される。翻訳時には glossary.yaml の用語集と language-guide.yaml の言語別ガイドが参照される。

バリデーション
翻訳完了後、以下の項目が自動で検証される。
- XML の整合性(well-formed チェック)
- プレースホルダーの数が source と target で一致するか
- 未翻訳文字列(
state="new")が残っていないか

インポート
バリデーションを通過した xcloc パッケージが、言語ごとに xcodebuild -importLocalizations でプロジェクトにインポートされる。

結果サマリー
最後に、翻訳結果のサマリーが言語別に報告される。
## ローカライズ結果
| 言語 | 翻訳数 | スキップ | 警告 | ステータス |
|------|--------|---------|------|-----------|
| en | 5 | 0 | 0 | ✅ 完了 |
| zh-Hans | 5 | 0 | 0 | ✅ 完了 |
| es | 5 | 0 | 0 | ✅ 完了 |
CLIでは下図のように翻訳内容についても表示してくれる。

Xcode での確認
インポート後、Xcode で String Catalog を開くと、翻訳された文字列が反映されていることを確認できる。

翻訳結果の確認と品質
AI 翻訳はそのまま出荷できるレベルになることも多いが、確認しておくべきポイントがある。
プレースホルダーの保持
SKILL.md でルールとして明示していても、稀にフォーマット指定子が変わることがある。バリデーションステップで検出されるが、警告が出た場合は該当箇所を手動で確認してほしい。
固有名詞の翻訳漏れ
glossary.yaml の do_not_translate に未登録の固有名詞が翻訳されてしまうケースがある。見つけたら glossary.yaml に追加して、次回以降の翻訳精度を上げていくとよい。
複数形カテゴリ
英語の one / other は比較的安定するが、アラビア語の6カテゴリなど複雑なケースでは翻訳漏れが起きる可能性がある。Xcode の String Catalog エディタで各カテゴリの翻訳状況を確認することをおすすめする。
文脈依存の翻訳
<note> 要素(翻訳者コメント)が設定されている文字列は比較的正確に翻訳される。逆に、コメントのない短い文字列(「Archive」が名詞か動詞かなど)は意図と違う翻訳になることがある。Xcode の String Catalog エディタでコメントを充実させておくと、翻訳精度が上がる。
まとめ
Claude Code の Agent Skills を使って、iOS アプリのローカライズワークフロー(エクスポート → AI翻訳 → インポート)を自動化した。
多言語対応はコストがかかる。対応したからといってユーザーが増えるわけではなく、しかし多言語化しなければユーザーが増えない。新規の文言リソースを追加するたびに翻訳コストも増加する。過去には Google Sheets から Localizable.strings を生成するなど、少しでもコストを下げようと工夫をしてきた。xcstrings の登場や AI の進化で翻訳コストは下がったものの、手作業のボトルネックは残っていた。今回のスキルはその課題に対する現時点での回答だ。
スキルは3ファイルだけのシンプルな構成で、SKILL.md にワークフロー全体の指示を書いている。翻訳対象の言語はプロジェクトの .xcstrings から動的に検出するため、Xcode 側で言語を追加するだけでスキルが追従する。用語集(glossary.yaml)と言語別ガイド(language-guide.yaml)はプロジェクトごとにカスタマイズして育てていくものだ。
実際に使ってみて、対応言語が多いプロジェクトほど自動化の恩恵が大きいと感じた。手作業では言語ごとに XLIFF を開いて翻訳する繰り返しか、XcodeのString Catalogエディタで編集するかだったが、スキルを使えばコマンド一つで全言語の翻訳が完了する。用語集や言語ガイドを充実させていくことで、翻訳品質も回を重ねるごとに向上していくと考えている。
一方で、AI 翻訳の結果をそのまま出荷するにはまだレビューが欠かせない。特に文脈依存の短い文字列や、複数形カテゴリが多い言語では注意が必要だ。今後は翻訳メモリとの連携や、過去の翻訳結果をフィードバックとして取り込む仕組みも検討していきたい。
スキルは GitHub で公開している。git clone してシンボリックリンクを張るだけで使えるので、ローカライズ作業の効率化に悩んでいる開発者はぜひ試してみてほしい。










