🗒️
[SwiftUI]LocalizedStringを便利に扱う
LocalizedStringの定義
- 基本的な使い方はこちら
- しかし、この方法ではキーをリテラルで記述する必要があるため、キーを
enum
に定義して呼び出せるようにする - そもそもSwiftGenを利用する選択肢があると思うが、ライブラリを入れるまでも無い規模であったり、サードパーティ製ライブラリの依存を増やしたく無い場合もあると思うので、そのようなケースの対応としてメモ
enum化
-
Localizable.strings
に下記のような設定があったとして、対応するenum
を定義する
// Localizable.strings
"SAMPLE_TEXT"="サンプル";
// Localization.swift
enum L10n: String {
case sampleText
}
- この
enum
の中にNSLocalizedString
を利用してString
を返す変数を定義しておく - また、このサンプルでは
LocalizedString
は大文字のスネークケース、enum
はキャメルケースで記述しているため、スネークケースに変換して呼び出せるように、String
のextention
も作っておく
reference: https://gist.github.com/dmsl1805/ad9a14b127d0409cf9621dc13d237457
// Localization.swift
enum L10n: String {
case sampleText
var localized: String {
NSLocalizedString(rawValue.snakeCased(), comment: "")
}
}
extension String {
func snakeCased() -> String {
let pattern = "([a-z0-9])([A-Z])"
let regex = try? NSRegularExpression(pattern: pattern, options: [])
let range = NSRange(location: 0, length: count)
return regex?.stringByReplacingMatches(in: self, options: [], range: range, withTemplate: "$1_$2").uppercased() ?? ""
}
}
- これで
L10n.sample.localized
のように呼び出せるようになる
パラメータを渡したい場合
-
"SAMPLE_PARAMETERIZED %@"="%@のサンプル";
など、パラメータを渡したいケースのために、引数を受け取るメソッドを追加する - 下記の例では、
sampleParameterized
→SAMPLE_PARAMETERIZED
と変換し、渡されたパラメータ数に応じて%@
を付加しているが、ここはもっと良い方法があるかもしれない
reference: https://qiita.com/hogehoge_samba/items/124840f1407b49efd73d
// Localization.swift
enum L10n: String {
case sampleText
case sampleParameterized
var localized: String {
NSLocalizedString(rawValue.snakeCased(), comment: "")
}
func localized(_ args: CVarArg...) -> String {
var value = rawValue.snakeCased()
args.forEach { _ in
value = "\(value) %@"
}
return NSString(
format: NSLocalizedString(value, comment: ""),
arguments: getVaList(args)
) as String
}
}
extension String {
func snakeCased() -> String {
let pattern = "([a-z0-9])([A-Z])"
let regex = try? NSRegularExpression(pattern: pattern, options: [])
let range = NSRange(location: 0, length: count)
return regex?.stringByReplacingMatches(in: self, options: [], range: range, withTemplate: "$1_$2").uppercased() ?? ""
}
}
- 一応これで
Text(L10n.sampleParameterized.localized("SwiftUI"))
と呼び出し、SwiftUIのサンプル
と出力されるようになる
Discussion