optional型(nil)でのつまずきを一通り解消できたところで、次に手をつけたのがアプリの多言語対応でした。日本語だけで作っていたアプリを英語にも対応させようとして、想像以上にいろいろなところでつまずいたので、その記録です。
1. 文字列を全部ハードコーディングしていたことに気づいた
多言語対応を始めようとして最初にぶつかったのが、そもそも画面の文字列をText("保存")のようにSwiftUIのコードへ直接埋め込んでいた、という問題でした。
翻訳を追加するには、まず文字列をコードから切り離して一元管理する必要があります。Xcodeの「String Catalog」(Localizable.xcstrings)機能を使うと、コード中の文字列を自動的に抽出してくれると知り、既存のビューを1つずつ見直して文字列をString Catalogに登録し直す作業から始めました。地味に時間がかかる作業でしたが、後からやるより最初からこの形で書いておくべきだったと痛感しました。
2. 英語訳を入れたらレイアウトが崩れた
日本語の「保存」は2文字ですが、英語の”Save”や、長い項目だと”Add to Favorites”のように文字数が大きく増えることがあります。日本語表示ではぴったり収まっていたボタンが、英語表示にした途端に文字がはみ出したり、折り返されてボタンの高さが変わってしまったりしました。
Button(String(localized: "save_button")) {
// 保存処理
}
.frame(width: 80) // 固定幅にしていたのが原因
原因は、ボタンやラベルの幅を数値で固定していたことでした。.frame(width:)で決め打ちにするのではなく、.fixedSize()や余白(.padding())ベースのレイアウトに変更し、文字数が変わっても崩れにくい作りに直しました。多言語対応は「翻訳を用意すれば終わり」ではなく、レイアウト自体を言語非依存に設計し直す作業でもあると実感しました。
3. Info.plistの権限説明文を翻訳し忘れていた
一通り画面の文字列を対応させて満足していたのですが、位置情報の許可を求めるダイアログだけ英語環境でも日本語のまま表示されることに後から気づきました。
原因は、カメラや位置情報などのアクセス許可時に表示される説明文(NSLocationWhenInUseUsageDescriptionなど)が、String CatalogではなくInfo.plistに直接書かれていたことでした。これらの項目もInfo.plistのローカライズ機能(InfoPlist.xcstrings)を使って別途翻訳を用意する必要があると分かり、慌てて対応しました。画面上の文言だけに気を取られていると、こうしたシステムダイアログの翻訳を見落としやすいと学びました。
4. シミュレータの言語切り替えで確認する習慣がなかった
翻訳を登録した後、Xcodeを日本語環境のまま実行して「表示されているから大丈夫」と思い込んでいたのですが、実はデフォルト言語(日本語)がそのまま表示されていただけで、英語訳が正しく反映されているか確認できていませんでした。
シミュレータの「設定」アプリから言語を英語に切り替えて実際に起動し直すか、Xcodeのスキーム編集画面で「Application Language」を明示的に切り替えて実行することで、ようやく英語表示を目視確認できました。コードを書いて終わりではなく、実際に言語を切り替えて自分の目で見るまでは対応完了と言えない、という当たり前のことを改めて実感しました。
まとめ
- 文字列はハードコーディードせず、最初からString Catalogなどで一元管理しておくと後が楽
- 翻訳後は文字数の増減でレイアウトが崩れやすい。固定幅ではなく可変レイアウトを意識する
- Info.plistの権限説明文など、画面外の文字列も翻訳対象。見落としやすいので注意
- シミュレータで実際に言語を切り替えて目視確認するまでが多言語対応
多言語対応は「文字列を訳すだけの単純作業」だと思っていましたが、実際にはレイアウト設計や見落としがちな箇所への配慮が必要な、意外と奥が深い作業でした。
次は、UserDefaultsとSwiftData、どっちを使うべきか迷った話をまとめます。
本記事は生成AI(Claude)を活用して執筆・編集しています。内容は実体験に基づき、執筆者本人が確認・監修しています。


コメント