初衷
公司本地化語(yǔ)言用的比較多,但是對(duì)于現(xiàn)有的一些語(yǔ)言本地化方案,不太滿意,于是想寫一個(gè)自動(dòng)化的腳本,達(dá)到優(yōu)雅的實(shí)現(xiàn)本地化語(yǔ)言目的
以 en.lproj/Home.strings 為例,內(nèi)容如下
"hello world" = "hello world";
原始的本地化就是這樣
bundle.localizedString(forKey: "hello world", value: nil, table: "Home")
丑陋的代碼。
于是有了各種本地化開源框架,比如 R.Swift
用了之后代碼就是這樣了
let string = R.string.localizable.homeWithName("hello world")
優(yōu)雅了很多,但我還是不太滿意,主要是key仍然是硬編碼的,key有可能寫錯(cuò),也可能沒有更新導(dǎo)致顯示錯(cuò)誤。于是我們通常用一個(gè)枚舉來(lái)表示key,如下:
struct Strings {
// Home: table name
enum Home: String {
case helloWorld = "hello world"
}
}
let string = R.string.localizable.homeWithName(Strings.Home.helloWorld.rawValue)
這樣避免了硬編碼這個(gè)key,只需要維護(hù)好相應(yīng)的枚舉就好了。但是仍然需要手動(dòng)維護(hù)這個(gè)枚舉,在添加key和修改key的時(shí)候 都需要額外的維護(hù),因此我想寫工具自動(dòng)化生成這個(gè)枚舉,每次更新strings file 的時(shí)候,這個(gè)腳本會(huì)更新對(duì)應(yīng)的枚舉Swift文件,這樣的話如果key更新了,就會(huì)產(chǎn)生相應(yīng)的編譯錯(cuò)誤,避免潛在的bug。
原理很簡(jiǎn)單讀取strings file, 然后生成source code到指定的文件夾
最終效果
struct Strings {
enum Home: String {
case helloWorld = "hello world"
func localized() -> String {
return bundle().localizedString(forKey: rawValue, value: nil, table: "Home")
}
func bundle() -> Bundle {
return CopyBundleProvider.shared.asBundle()
}
}
}
使用
let string = Strings.Home.helloWorld.localized()