こんにちは。もぐめっとです。
Qiita初投稿です。
先日、大先輩のfmtonakai大師匠からすごい目からウロコのstoryboardのローカライズ対応について教えてもらいました。
普段は自分のブログに書いているのですが、あまりにも目からウロコ過ぎたのでQiitaで共有しておきます。
storyboardにローカライズのキーを指定できるようにする
extension UILabel {
@IBInspectable
private var localizedKey: String? {
get { fatalError("only set this value") }
set {
if let newValue = newValue {
text = newValue.localized()
}
}
}
}
extension String {
func localized() -> String? {
return NSLocalizedString(self, comment: "")
}
}
こう書いておくだけで、Android Studioのようにstoryboardからキーを設定してローカライズすることができるようになります。
すごい!画期的!!
ローカライズのキーtypoを防ぐ その1
このままだと、typoとかしたときにローカライズのキーがそのまま表示されてしまうのでローカライズ漏れに気づけるように改良してみました。
extension String {
private static let localizedEmptyKey = "##not exists##"
func localized() -> String {
let string = NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: String.localizedEmptyKey, comment: "")
if string == String.localizedEmptyKey {
fatalError("not exists localized key")
}
return string
}
}
キーが無かった場合には強制的にアプリを落としてしまうことによってキーの漏れに気づけるようになりました。
ローカライズのキーtypoを防ぐ その2
その1の対応だと、画面を表示したときでないとtypoに気づけません。
そこで、ビルド時にキーのチェックをしてtypoに気づけるようにさらに改良してみました。
Build Phasesに下記スクリプトを追加するだけ!
# !/bin/bash
for file in `\find . -name \*.storyboard`; do
IFS=$'\n'
for xmlKey in `\grep 'keyPath="localizedKey"' ${file}`; do
localizedKey=`echo $xmlKey | sed -e 's/.* keyPath="localizedKey" value="\([0-9a-zA-Z_-]*\)".*/\1/g'`
for localizedStringFile in `\find ${SRCROOT} -name Localizable.strings`; do
grep "\"${localizedKey}\" =" $localizedStringFile > /dev/null 2>&1
if [ $? != 0 ]; then
echo "not exists key '${localizedKey}' in ${localizedStringFile}"
exit 1
fi
done
done
done
storyboardで設定されているlocalizedKeyをひっぱてきてLocalizable.stringsのファイルと突き合わせて存在しなければエラーを吐き出します。
まとめ
Android Studioに比べるとxcodeで至らぬところというのはまだまだありますが、今回の対応でLocalizable.stringsに文言を集約することができるようになり、よりローカライズがしやすくなってとってもウロコな方法でした。
storyboardでのローカライズはこの方法でやって、コードでの動的なローカライズについてはR.swiftやswiftgenなどで対応していって適材適所に使ってローカライズしていけるといいと思います。
今回の検証コードはこちらにおいてあります。
Special Thanks fmtonakai