2014年から個人でアプリ開発を続けてきて、累計のダウンロード数が5,000万を超えた今も、一番地味に困っていた作業がローカライズです。
壁紙アプリや癒し系アプリを複数抱えていると、新しい言語への対応が後回しになりがちです。機能追加のたびに新しいキーが増えるのに、英語版の Localizable.strings しか更新されていない状態が続く。気づいたときには抜け漏れのキーが数十個になっていて、対応言語ごとにファイルを開いて照らし合わせる作業が週末を半日つぶすような重さになっていました。
Claude Code をこの作業に組み込んでから、状況は大きく変わりました。完全に自動化できたわけではありませんが、作業の「重さ」が変わった感覚があります。
なぜ個人開発でローカライズが積み残しになるのか
複数のアプリを一人で回していると、優先順位が常に「動く機能を作ること」に向きます。新しいUIコンポーネントを追加したとき、まず日本語と英語だけで動作確認して、他の言語は「あとで」とファイルに TODO コメントを入れておく。
この「あとで」が積み重なります。
私の場合、壁紙アプリで対応している言語は日本語・英語・中国語(繁体字)・韓国語の4つです。コア機能の追加ごとに4ファイルを同期しなければならないのですが、現実的には英語版のみ先行して、他の言語はリリース後に修正する対応が続いていました。
App Store のレビューに「翻訳が途中で英語になる」という指摘が来るたびに修正していましたが、その都度時間を取られるのは非効率でした。
Claude Code に Localizable.strings を渡す基本アプローチ
最初に試したのは、単純に Claude Code のセッションに strings ファイルを読み込ませて、足りないキーを補完してもらうことでした。
# プロジェクトのルートで実行
claude "以下のファイルを読み込んで、
en.lproj/Localizable.strings に存在するキーのうち
zh-Hant.lproj/Localizable.strings に存在しないキーの
翻訳候補を生成してください。
翻訳は自然な繁体字中国語で、他のキーのトーンと合わせてください。"ただし、このアプローチにはすぐに限界が見えました。キーの数が多いとコンテキストウィンドウに収まらず、途中で切れることがあります。特に数百キーを超えると、後半の翻訳精度が不安定になりました。
そこで作業を分割する方法に切り替えました。
実際のワークフロー:差分を取り出してから渡す
今使っているフローはこうです。まず差分を取り出すシェルスクリプトを用意して、必要な量だけ Claude Code に渡します。
#!/bin/bash
# diff_strings.sh — en.lproj の未翻訳キーを抽出する
SOURCE="en.lproj/Localizable.strings"
TARGET="$1" # 例: zh-Hant.lproj/Localizable.strings
# ソースから全キーを取得
grep -oE '"[^"]+"\s*=' "$SOURCE" | sed 's/\s*=//' | tr -d '"' > /tmp/source_keys.txt
# ターゲットから全キーを取得
grep -oE '"[^"]+"\s*=' "$TARGET" | sed 's/\s*=//' | tr -d '"' > /tmp/target_keys.txt
# 差分(ソースにあってターゲットにないキー)
diff /tmp/source_keys.txt /tmp/target_keys.txt | grep '^<' | sed 's/^< //' > /tmp/missing_keys.txt
# 差分キーの数を確認
MISSING_COUNT=$(wc -l < /tmp/missing_keys.txt)
echo "未翻訳キー数: $MISSING_COUNT"
# 差分キーに対応するソース値を抽出
while IFS= read -r key; do
grep "\"$key\"" "$SOURCE"
done < /tmp/missing_keys.txtこのスクリプトで差分を取り出してから、Claude Code に渡します。
# 差分を取り出す
./diff_strings.sh zh-Hant.lproj/Localizable.strings > /tmp/missing_zh.txt
# Claude Code で翻訳生成
claude "以下はiOSアプリ(壁紙アプリ)のLocalizable.stringsの英語版キーです。
繁体字中国語への翻訳を、Localizable.strings形式で生成してください。
アプリは壁紙閲覧・ダウンロードがメインの機能です。翻訳は簡潔で親しみやすいトーンで。
$(cat /tmp/missing_zh.txt)"Claude Code が生成した翻訳を直接ファイルに追記する前に、必ず目視確認を挟みます。機械翻訳っぽい硬さが出ることがあり、特にボタンラベルやエラーメッセージは人間が確認した方が品質が安定します。
気づいたこと:思っていたより「コンテキスト依存」だった
実際に使って気づいたのは、Claude Code への渡し方よりも「アプリのコンテキスト説明」の方が翻訳品質に大きく影響するという点です。
最初は strings ファイルだけを渡していましたが、翻訳が画面の文脈と噛み合わないケースが出ました。例えば "save_button_title" = "Save" という単純なキーでも、何を保存するボタンなのかによって適切な翻訳が変わります。壁紙アプリなら「保存」か「ダウンロード」か、中国語圏のユーザーにどちらが自然に見えるか。
解決策として、プロジェクトルートの CLAUDE.md にアプリの概要を書き足しました。
# アプリ概要
このアプリは壁紙の閲覧とダウンロードが主な機能です。
- メインユーザー: 10代〜30代のスマートフォンユーザー
- トーン: フレンドリー・カジュアル(丁寧語は使わない)
- 主な機能: 壁紙ブラウズ、カテゴリ絞り込み、画像保存、お気に入り管理
この数行を CLAUDE.md に追加してから、翻訳の文脈精度が上がりました。Claude Code がセッション開始時にプロジェクトのコンテキストを読み込むため、追加の説明なしに適切なトーンで翻訳を出してくれるようになりました。
翻訳品質を確認するプロセス
Claude Code が生成した翻訳を確認するために、もう一段階の自動チェックを入れています。
# 翻訳後のファイルで空のバリューがないか確認
grep '= ""' zh-Hant.lproj/Localizable.strings && echo "空バリューあり" || echo "空バリューなし"
# キーの件数一致確認
SOURCE_COUNT=$(grep -c '"' en.lproj/Localizable.strings)
TARGET_COUNT=$(grep -c '"' zh-Hant.lproj/Localizable.strings)
echo "EN: $SOURCE_COUNT lines, ZH-HANT: $TARGET_COUNT lines"件数確認だけでは内容の品質は担保できませんが、明らかな抜け漏れはここで検出できます。
最終的な確認は、アプリをビルドして実機または Simulator で各言語を切り替えて目視します。Claude Code が生成した翻訳をそのまま出荷するのではなく、自分の目で通すワンステップを省略しないことにしています。両家の祖父が宮大工だったことを近くで見て育ったので、丁寧に仕上げるという感覚は、コードの世界でも引き継いでいきたいと思っています。
積み残しゼロを維持するために
このワークフローを定着させてから、「リリース前に翻訳が間に合わなかった」という状況がほぼなくなりました。
大切なのは、翻訳作業を機能追加と分けて考えないことです。新しいキーを英語版に追加したタイミングで diff_strings.sh を走らせて差分を確認し、翻訳が必要ならその場で Claude Code に渡す。作業を週末にまとめてやろうとすると、また積み残しになります。
次にやりたいのは、この差分チェックを Xcode のビルドスクリプトに組み込むことです。ビルド時に未翻訳キーがあれば警告を出す仕組みにすれば、積み残しの存在に早く気づけます。
まず diff_strings.sh を試してみたい方は、対応言語が最も遅れているファイルを一つ選んで差分を取り出すところから始めてみてください。キー数が多くても、50件程度のバッチに分けて Claude Code に渡せば精度が安定します。
同じように一人で複数アプリを回している方の同じ課題に取り組んでいる方の参考になれば幸いです。