对于App中的国际化,大家想必已是轻车熟路了。
不过对于某些情况下我们需要对库中的字符串做国际化操作,这篇博文就来探讨一下如何完成这一任务。
其实理论上可以将库中的国际化字符串数据放在App的国际化文件中,但这样做打破了封装性,假如有100个App使用该库,则需要在创建100次国际化字符串,违反了DRY原则。
下面就静态库和动态库两种情况分别讨论。
1.静态库的国际化
静态库中是不能放入资源文件的,这意味着国际化字符串一定要放在静态库项目外部:
myStaticLib.a
StaticRes.bundle
所以我们在Xcode中新创建一个bundle文件,保存到本地,但不要对其做任何编辑。在Finder中进入该bundle文件,在其中根据需要创建若干文件夹,然后将对应字符串文件放入其中:
fileprivate class ResBundle:Bundle{
static var bundle:Bundle = ResBundle()
private init(){
//资源bundle文件必须嵌入App的主bundle中,下面一句从主bundle中取得资源bundle的路径
let resBundlePath = Bundle.main.path(forResource: resBundleName, ofType: "bundle")!
super.init(path: resBundlePath)!
}
}
func hyLocalizedString(key:String,comment:String="")->String{
return NSLocalizedString(key, tableName: "HyCommon", bundle: ResBundle.bundle, value: "", comment: comment)
}
我们用如下方式取得国际化字符串:
let myString = hyLocalizedString("contentString")
这样做的好处是,我们只要创建1份与该静态库相关的资源文件就可以被任意数量的App所使用。
2.动态库的国际化
对于动态库来说,情况貌似简单了不少。因为动态库是可以嵌入资源文件的,所以我们没必要单独创建一个bundle,而是将国际化的数据直接放在动态库里面就可以了。
在Xcode中打开动态库项目,在其中添加xxx.strings文件。是的,你没看错,strings文件名可以随意。因为你别指望直接使用NSLocalizedString(…)之类的方法来取得它们。
为什么呢?
其原因是NSLocalizedString默认是从主Bundle中获取指定名称的strings文件(Localizable.strings),但现在我们的资源文件是在动态库里,所以有必要写一个帮助方法来完成国际化功能.
这个帮助方法和上面静态库的实现差不多,唯一不同的是对资源路径的获取:
private init(){
//取得动态库所在的子目录
let frameworkPath = Bundle.main.path(forResource: "Frameworks", ofType: nil)!
//取得动态库本身的路径
let resBundlePath = URL(fileURLWithPath: frameworkPath, isDirectory: true).appendingPathComponent(resBundleName).path
super.init(path: resBundlePath)!
}
动态库字符串国际化的获取代码和静态库完全一样,这里就不再介绍了。
总结
综上所述,无论是静态库还是动态库,我们只要把握2点:
- 资源文件的名称
- 资源文件中strings文件的名称
就可以一招鲜吃遍天,无论何种情况都可以轻松搞定了。
以上就是iOS静态库和动态库中国际化的实现,感谢观赏。