xckitでClaude Codeに翼を授ける
梅雨明けが待ち遠しい今日この頃ですが、エアコンがガンガン効いた部屋でコーディングするのも悪くないと思えるK@zuki.です。
Xcode String Catalogsの管理、皆さんはどうしていますか?
正直なところ、Xcode 15から導入された.xcstringsファイルって「JSON形式になって便利そう」「でもデカくなると見づらい...」「AIに投げるとトークン爆食い...」って思っちゃいますよね。
俺も常々そう思っています。
でも、この問題をClaude Codeがある程度解決するCLIツールを作ったら、ローカライズ作業が劇的に効率化できました。
しかも、AIツールとの連携も考慮した設計にすることで、楽に翻訳作業を進めるワークフローが実現できました。
今回は、私が開発しているxckitというツールで実現したローカライズ作業の効率化について共有したいと思います。
既に似たようなツールはあるものので、既に使っているツールがあれば気にしなくてOKです。
要約
- Claude Codeが.xcstringsファイルを直接操作できるための補助CLIツールを作った
- AIが自律的に未翻訳キーを発見・翻訳・更新できる
- 人間は「翻訳更新して」と言うだけでOK
- AIとの協調作業を前提とした設計
なぜXcode String Catalogsの管理が面倒なのか
まず、Xcode 15で導入された.xcstringsファイルの特徴を整理してみましょう。
従来の.stringsファイルと比べて、いくつか大きな変化があるわけです。
JSON形式になったメリット・デメリット
.xcstringsファイルは、こんな感じのJSON構造になってます。
{
"sourceLanguage": "en",
"strings": {
"welcome_message": {
"comment": "アプリ起動時に表示",
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Welcome!"
}
},
"ja": {
"stringUnit": {
"state": "needs_review",
"value": "ようこそ!"
}
}
}
}
}
}
構造化されていて良さそうに見えるんですが、実際に使ってみるといくつかの課題に直面することになります。
実務で直面する課題
アプリの規模が大きくなってくると、こんな問題が出てきます。
- ファイルサイズが巨大になる(数千行とか小さい方)
- Xcodeを開かないと最新の翻訳状況が把握できない
- 未翻訳のキーを見つけるのが大変
- AIツールに投げようとすると無駄なトークンを消費
特に最後の点、ChatGPTやClaudeに「この部分の翻訳をお願い」って投げるとき、関係ない部分まで含めて数千行のJSONを送るのは非効率すぎますし、数千行の時点でコンテキスト超過が発生しやすいです。
そのため、これをなんらか補助することができないか?と考えたわけです。
AIが賢さを発揮できない現状の問題
Claude Codeに「新しい機能の翻訳も更新して」と言っても、
- 巨大な.xcstringsファイルから未翻訳部分を探すのが大変(grepやsed、jqなどを駆使してもそこそこ大変)
- どのキーが未翻訳かプログラム的に判断できない
- 翻訳対象を特定するのに無駄な処理が必要
- 結果、人間が手動で指示するのと変わらない
これじゃAIの能力を活かしきれていないので、怠惰な人間としてはもう少し楽にしたかったんですよね。
となると、やっぱりそのためにツールを書くのがプログラマっていうもんでしょう。
xckitでClaude Codeに翼を授ける
そんな悩みを解決するために作ったのがxckitです。
Claude Codeが.xcstringsファイルを直接操作できるようにしたことで、AIが自律的に翻訳作業を進められるようになりました。
すでに似たようなツールは多くあるんですが、あらゆる環境でも簡単にインストールすることができると楽なのでGoで書いています。
まだ対応していませんが、closestと同様にaquaでインストールできるようにはそのうちする予定です。
基本的な使い方
まず、インストールから。GitHubのリリースページからダウンロードできます。
# GitHubのリリースページから環境に合ったバイナリをダウンロード
# https://github.com/corrupt952/xckit/releases
# ダウンロードしたファイルを解凍してパスの通った場所に配置
tar xzf xckit_darwin_arm64.tar.gz
mv xckit /usr/local/bin/ # または適当な場所に
あとは、.xcstringsファイルがあるディレクトリで使うだけです。
Claude Codeへのインストラクション
CLAUDE.mdやSlash Commandsのどちらでもいいんですが、以下のような情報を与えておくとスムーズです。
# Localization Management
# Check translation status
xckit status -f SpriteFrame/Localizable.xcstrings
# List untranslated keys
xckit untranslated -f SpriteFrame/Localizable.xcstrings
# List untranslated keys for a specific language
xckit untranslated -f SpriteFrame/Localizable.xcstrings --lang ja
# Set translation for a specific key and language
xckit set -f SpriteFrame/Localizable.xcstrings --lang ja "キー" "翻訳文"
# Example: Add translations for all supported languages
xckit set -f SpriteFrame/Localizable.xcstrings --lang ja "Cancel" "キャンセル"
xckit set -f SpriteFrame/Localizable.xcstrings --lang es "Cancel" "Cancelar"
xckit set -f SpriteFrame/Localizable.xcstrings --lang ko "Cancel" "취소"
xckit set -f SpriteFrame/Localizable.xcstrings --lang zh-Hans "Cancel" "取消"
xckit set -f SpriteFrame/Localizable.xcstrings --lang zh-Hant "Cancel" "取消"
翻訳状況の把握
Claude Codeはまず現在の翻訳状況を確認するためには、以下のコマンドを実行して、「日本語の翻訳が80%しか完了していない」ことを出力結果から受け取ることができます。
$ xckit status
Translation Status
==================
Source Language: en
Total Keys: 150
Languages: [ja, zh-Hans, ko]
Progress by Language:
--------------------
ja : 120/150 translated (80.0%)
zh-Hans : 100/150 translated (66.7%)
ko : 75/150 translated (50.0%)
これらをベースに、Claude Codeが現在の状態を把握しながら進めることができます。
Claude Codeが未翻訳キーを発見
次にClaude Codeは未翻訳のキーを特定するためのコマンドがあります。
以下では日本語が未翻訳の場合のキーを探しているケースです。
$ xckit untranslated --lang ja
login.title:
en: translated - Sign In
ja: missing
login.subtitle:
en: translated - Enter your credentials
ja: missing
error.network_failure:
en: translated - Network connection failed
ja: missing
コンテキストを適切にしておくことで、Claude Codeはこの出力を元に実装箇所の特定をし、文脈や画面に応じた翻訳が比較的行われます。
--lang
を指定しない場合は、いずれかの言語の未翻訳状態を取得することができます。
また前方一致により、機能単位で翻訳を進められるのもポイントです。(grepでええやん)
$ xckit untranslated --lang ja --prefix "login"
login.title:
en: translated - Sign In
ja: missing
login.subtitle:
en: translated - Enter your credentials
ja: missing
Claude Codeが翻訳を更新
Claude Codeは生成した翻訳を直接適用することができます。
今はまだ1つずつしか更新できるI/Fがないですが、以下のように更新していくことが可能です。
$ xckit set --lang ja "login.title" "サインイン"
$ xckit set --lang ja "login.subtitle" "認証情報を入力してください"
$ xckit set --lang ja "login.button" "ログイン"
Claude Codeはキーの構造を理解して、一貫性のある翻訳を自動で適用してくれるので、人間は確認するだけでOKです。
大規模プロジェクトでの活用
大規模プロジェクトでは、機能単位で翻訳を進めることが重要です。
# 設定画面関連の翻訳を更新
$ xckit untranslated --prefix "settings"
# エラーメッセージの翻訳を更新
$ xckit untranslated --prefix "error"
# ダッシュボード関連の翻訳を更新
$ xckit untranslated --prefix "dashboard"
Claude Codeはプレフィックスを活用して、関連するキーをまとめて翻訳し、一貫性を保ちます。
実装のこだわりポイント
開発していて、いくつかこだわったポイントがあります。
Go言語での実装
なぜGoを選んだかというと、
- シングルバイナリで配布できる(依存関係なし)
- クロスプラットフォーム対応が楽
- JSONの扱いが得意
- 起動が速い
特に最後の点、頻繁に使うCLIツールは起動速度が命ですよね。
.xcstringsファイルの構造を壊さない
Xcodeが生成するJSONの構造やフォーマットを維持するように気をつけました。
// 元のインデントやキーの順序を保持
encoder := json.NewEncoder(file)
encoder.SetIndent("", " ")
encoder.SetEscapeHTML(false)
xckitで編集してもXcodeで問題なく開けることを保証してます。
が、0.0.1でしくじったので、変更前にバックアップをとるか、コミットしておいていつでも戻せるようにしてあると良いです。
実際の使い方
実際の使い方としては、事前準備としては
- xckitのインストール
- インストラクション(前述)
のみになります。
そして、実際に使っている例を紹介します。
> 日本語のまま未翻訳になっている文字列をViewから探しだし、他のViewファイルと同様に構造化キーで翻訳可能な状態にしてください。その後ユーザーにビルドをお願いし、問題なければ所定の手順で翻訳作業を進めてください。他のViewファイルを必ず参考にしてください。
といった形です。
まだ調整中なため、最終的にはSlash Commandsになる予定ですが、今はこれを打つだけでもかなりの速度で翻訳作業を進めてくれます。
さてお気づきかもしれませんが、
将来的な拡張性
今後の展開として、
- AIツールとのより密な連携も検討中(MCPとか)
- 計算量の改善
あたりはやっておきたいですね。
俺がやっている範囲では問題ない計算量なんですが、少ないに越したことはないので。
まとめ
Claude Codeが自律的に翻訳作業をできるようにする、これが私がxckitを作った理由です。
「翻訳更新して」の一言で、
- AIが未翻訳キーを発見
- キー構造から意味を理解
- 適切な翻訳を生成
- ファイルを直接更新
この一連の作業をAIが完全に自動化してくれる。
人間はコア機能の開発に集中できる。
これが、AIと人間が協調する現代の開発スタイルだと思います。
とはいえ、今回紹介しただけだとまだ完全な自動化とはいえず、generate-strings-file
などを使って翻訳ファイルの更新処理などが必要になるので、それはまた今度。
皆さんもClaude CodeでiOS/macOSアプリを開発する際は、ぜひxckitを使ってみてください。
AIが賢く効率的に翻訳作業を進めてくれるのを体験できるはずです。
xckitのコードはGitHubで公開しているので、AIとの連携をさらに強化するアイデアがあればPRお待ちしてます。
Discussion