リリースが間近に迫ると、翻訳ベンダーから複数の .xcloc または .xliff ファイルが納品されることがあります。開発者が普段使っている作業領域で直接ダブルクリックして取り込めば、一見すると効率的です。しかし実際には、古い翻訳キー、誤ったターゲット言語、破損したプレースホルダーまでプロジェクトへ混入するおそれがあります。より確実なのは、クラウドMac上に一時的な検証ディレクトリを用意し、現在のコミットから基準データをエクスポートしたうえで、納品物を事前検査し、最後に取り込み、差分確認、ビルドを実行する方法です。
検証環境を固定する
検証ノードはクリーンなコミットから開始します。ローカライズデータをすでに取り込んだ作業領域を再利用したり、未コミットの変更が残っているディレクトリでテストしたりしないでください。納品バッチごとに一時ブランチまたは独立したworktreeを作成できます。
git fetch origin
git worktree add ../localization-review origin/main
cd ../localization-review
git switch -c review/localization-batch
xcodebuild -version
git status --short
xcodebuild -version、コミットSHA、対象Scheme、納品バッチをログへ記録します。チームで複数のXcodeバージョンを使用している場合は、対話型ターミナルと自動処理で異なるツールチェーンが呼び出されないよう、DEVELOPER_DIR も明示的に設定します。
export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"
xcode-select -p
git rev-parse HEAD
ローカライズ検証の基準は「ファイルを開けること」ではありません。同一のコミット、同一のXcodeツールチェーン、同一のエクスポートパラメーターから、説明可能な結果を再現できることです。
GPUMiniのクラウドMacで実行する場合は、まずコンソールで現在選択可能な構成を確認し、検証に使用するノードを選びます。この作業は通常、高い並列性能を必要としません。ただし、取り込み後に大規模なプロジェクトを完全ビルドする場合は、メモリとディスクの空き容量も計画に含める必要があります。
現在のプロジェクトから基準データをエクスポートする
.xcodeproj ではプロジェクト引数を使用してエクスポートできます。Workspaceを使用するプロジェクトでは -workspace に置き換え、共有可能なSchemeを指定します。次の例では簡体字中国語、日本語、フランス語をエクスポートしています。言語を追加するには -exportLanguage を繰り返し指定します。
mkdir -p Artifacts/Baseline
xcodebuild \
-project ExampleApp.xcodeproj \
-scheme ExampleApp \
-exportLocalizations \
-localizationPath Artifacts/Baseline \
-exportLanguage zh-Hans \
-exportLanguage ja \
-exportLanguage fr
エクスポートが完了したら、受領した翻訳をすぐに上書きするのではなく、先にファイル一覧を保存します。
find Artifacts/Baseline -type f -print0 \
| sort -z \
| xargs -0 shasum -a 256 > Artifacts/baseline.sha256
基準データからは、現在のプロジェクトに存在する翻訳対象単位、原文の内容、Xcodeが認識するターゲット言語という3点を確認できます。納品ファイルに基準データには存在しないキーが含まれている場合、古いコミットを基に翻訳された可能性があります。基準データ側に未翻訳の単位が大量に追加されている場合は、最近追加された機能が納品範囲から漏れている可能性があります。
取り込み前に構造とプレースホルダーを検査する
XLIFFの実体はXMLです。まずシステムツールで形式を検証し、その後に言語属性と翻訳単位数を抽出します。正規表現でXMLを書き換えないでください。事前検査では読み取りのみを行い、修正はローカライズツールまたはレビュー済みのスクリプトへ戻して実施します。
find Incoming -name "*.xliff" -print0 |
while IFS= read -r -d '' file; do
echo "Checking $file"
xmllint --noout "$file"
xmllint --xpath \
'string(/*[local-name()="xliff"]/*[local-name()="file"][1]/@target-language)' \
"$file"
echo
done
特に重大なのがプレースホルダーの不整合です。%@、%d、位置指定パラメーター、およびString Catalogが生成する変数は、原文と訳文の間で意味的な対応を維持する必要があります。単にパーセント記号の数を比較するだけでは不十分です。%%、書式幅、位置指定パラメーターはそれぞれ意味が異なるためです。XMLパーサーを使用して各 trans-unit の source と target を個別に読み取り、プレースホルダーを正規化してから多重集合として比較することを推奨します。
| 検査項目 | ブロック条件 | 対応方法 |
|---|---|---|
| XML構造 | xmllint がゼロ以外を返す |
納品ファイルを差し戻す |
| ターゲット言語 | ファイルのバッチと一致しない | 言語マッピングを修正して再エクスポートする |
| 翻訳単位 | 未知のIDが含まれる | 基準データのコミットを確認する |
| プレースホルダー | 型または数が一致しない | 訳文を修正して再検査する |
| 空の訳文 | 重要な画面のターゲットが空 | フォールバックを許可するか確認する |
ユーザーに表示される書式文字列については、改行文字、エスケープ文字、複数形の分岐も抜き取り確認します。言語によってプレースホルダーの順序を変更することはできますが、位置指定パラメーターを使用する場合は、インデックスが有効なままでなければなりません。
分離したディレクトリへ取り込み、差分を確認する
事前検査を通過したら、.xcloc パッケージを1つずつ取り込みます。各取り込みの直後に状態を記録しておけば、異常の原因となった納品物を特定しやすくなります。
mkdir -p Artifacts/Logs
for package in Incoming/*.xcloc; do
name="$(basename "$package" .xcloc)"
xcodebuild \
-project ExampleApp.xcodeproj \
-importLocalizations \
-localizationPath "$package" \
2>&1 | tee "Artifacts/Logs/import-${name}.log"
test "${PIPESTATUS[0]}" -eq 0 || exit 1
git status --short
done
取り込みに成功しても、検証が完了したとは限りません。まず git diff --stat で影響範囲を確認し、その後にファイルごとの差分を読みます。通常の変更は、String Catalog、文字列リソース、または対応する言語ディレクトリに集中するはずです。Scheme、ビルド設定、署名設定、無関係なプロジェクトファイルに変更が発生した場合は、作業を中断して原因を調査します。
git diff --stat
git diff --check
git diff -- '*.xcstrings' '*.strings' '*.stringsdict' 'project.pbxproj'
git diff --check では、一部の行末空白や競合の痕跡を検出できますが、翻訳の意味までは判定できません。「追加、削除、変更された翻訳単位」の概要を生成し、取り込みログとともにパイプラインの成果物として保存することを推奨します。
ビルドと再エクスポートで検証を完結させる
最後に、対象Schemeをクリーンビルドします。プロジェクトに複数のアプリケーションターゲットや拡張機能が含まれている場合は、最小構成のライブラリターゲットだけでなく、実際のリリース経路を網羅する必要があります。
set -o pipefail
xcodebuild \
-project ExampleApp.xcodeproj \
-scheme ExampleApp \
-configuration Release \
-destination 'generic/platform=iOS Simulator' \
clean build |
tee Artifacts/Logs/localization-build.log
ビルドに成功したら、取り込み後のプロジェクトからXLIFFをもう一度エクスポートし、基準データと比較します。再エクスポートにより、訳文が実際にはプロジェクトへ反映されていない、言語コードのマッピングが誤っている、取り込み後も未翻訳単位が残っている、といった問題を検出できます。比較時には、単なる並び順の違いやツール生成のメタデータを無視し、翻訳単位の原文、ターゲットテキスト、状態、注記だけを確認します。
保守可能な検証パイプラインでは、ツールチェーンとコミット情報、事前検査レポート、取り込み差分の概要、ビルドログという4種類の証跡を明確に保存する必要があります。失敗時には作業ディレクトリを自動削除せず、まずその状態を保持します。成功後は一時worktreeを削除し、次の納品バッチへ古い状態が引き継がれないようにします。
最終ゲートは、XMLを解析できること、ターゲット言語が正しいこと、プレースホルダーの集合が一致すること、未知の翻訳単位がゼロであること、差分の範囲が想定どおりであること、対象Schemeのビルドに成功すること、という条件に集約できます。これにより、クラウドMacは人の記憶だけに依存して管理される別の取り込み環境ではなく、再現可能なローカライズ検証ノードとして機能します。
よくある質問
翻訳の確認前にXLIFFを再度書き出す理由は何ですか?
現行プロジェクトが認識する翻訳単位、原文、対象言語を固定でき、古いキーや未知のキーを取り込み前に見つけられるためです。
XLIFFの取り込み成功だけで公開可能と判断できますか?
できません。プレースホルダー、複数形、生成された差分を確認し、対象Schemeのクリーンビルドも実行する必要があります。
メインの作業領域へ直接取り込んでもよいですか?
推奨しません。一時ブランチまたは別worktreeで実行し、ログと差分を保存して、確認済みのリソースだけをマージします。
開発やビルド作業に使うクラウドMacを選ぶ
2種類のM4構成、4種類のレンタル期間、販売中の4つのノードを比較し、用途に合わせてデプロイします。