String Catalogs 導入時に検討したこと
概要
Xcode 15 から Strings Catalogs が利用できる。
既存の iOS プロジェクトに String Catalogs を導入する際に検討したことをまとめておきたい。
環境
- Xcode バージョン: 15.1
- サポート iOS バージョン: iOS 15 ~
確認したいこと
既存プロジェクトへのマイグレーション
Xcode のマイグレーション機能によって、 .strings
ファイルから .xcstrings
ファイルへの移行が容易に行える。 IB (Storyboard, Xib) や InfoPlist も対象にすることができる。
既存の .strings
ファイルが消滅してしまうため、R.swift などでコード生成している場合は、コード利用箇所を一気に修正する必要があるため、段階的な置き換えには向いていない。
そのため、ある程度の規模のプロジェクトであれば、Localizable.strings
, InfoPlist.strings
をそれぞれ手動で .xcstrings
ファイルに移行していくことになる。
.xcstrings
への自動同期
下記のようなローカリゼーション API にローカライズしたいテキストを渡すと、ビルド時に自動で .xcstrings
にキーバリューが同期される。
ただし、自動同期させるにはターゲットの Build Settings > Localizations > Use Compiler to Extract Swift Strings を Yes
にしておく必要がある。
デフォルトではキーバリューは同じ値が設定される。
// SwiftUI
Text("Hoge")
// UIKit
String(localized: "Hoge")
ローカライズしたくないテキストは以下のように避ける。
// SwiftUI
Text(verbatim: "Hoge")
// UIKit
String("Hoge")
使用元 (コード側) でテキストが変更された場合、 .xcstirngs
のキーバリューはそのまま残り (レビュー済みの場合) 、state : STALE
となる。そして変更後のテキストが state: NEW
として新たにキーバリューとして追加される。
.xcstrings
で state を確認すればローカライズ漏れはいくらか防げる。
.xcstrings
への手動同期
ローカライズテキストを .xcstrings
に手動で追加していくことも可能である。
テキストごとに自動同期か手動同期か設定することができる。
.xcstrings
ファイルに手動追加した場合は、デフォルトで手動同期となる。
キー名をカスタムで命名したい場合は、手動同期で運用することが前提となる。
当然だが手動同期の場合は、テキスト側が変更されても .xcstrings
へ反映されない。
コード生成ツールを利用したいところ。
手動同期か自動同期のどちらで運用していくか
自動同期の場合は コード -> .xcstrings
、手動同期の場合は .xcstrings
-> コード の流れで反映する運用となる。
コード生成ライブラリを使うかどうかなど、プロジェクトごとの運用に左右される。
ファイル分割について
AAALocalizable.xcstrings
, BBBLocalizable.xcstrings
, ...など自由にファイル名を変えて分割可能。
ファイルを分割した場合、以下のようにファイル名を指定してコードからアクセスできる。
// SwiftUI
Text("Hoge", tableName: "AAALocalizable")
// UIKit
String(locaclized: "Hoge", table: "BBBLocalizable")
同一ファイル内ではキーの重複が許容されないが、別ファイルであれば同じキー名で異なるバリューを設定できる。
コード生成ツール
.xcstrings
のローカライズテキストでも、可能であれば R.swift や SwiftGen のようなコードの自動生成ツールを利用したい。
軽く探してみたところ、現状で使えそうなライブラリは XCStringsTool くらいであった。
R.swift や SwiftGen などのようにコードを自動生成してくれるので、ローカライズテキストに安全にアクセスすることが可能になる。
LocalizedStringResource
のエクステンションにコード生成してくれるっぽい。
これが iOS16 以降でないと利用できないため iOS 15 サポートを切ることができれば導入できる。
String で使いたいという Issue は立っていたが、 今のところ対応される見込みは薄い。
iOS 15 でも使えるような対応がマージされたっぽい。
R.swift や SwiftGen のリポジトリにも String Catalogs へ対応されるかどうか確認の Issue はあったが、対応される予定はなし。
エクスポート・インポートについて
言語ごとに .xcstrings
ファイルをまとめた .xcloc
ファイルをエクスポート・インポートできる。
.xcstrings
ファイルが JSON 形式のファイルなので、その他ファイルとの変換はスクリプトを書くなどで対応することになりそう。