swift 发布于 2017年08月01日
iOS 中处理多语言
NSLocalizedString
是 iOS 中处理多语言显示的标准方法,相信大家都已经不陌生,无论你开发的 APP 是否真的需要多语言,使用 NSLocalizedString
而不是直接把字符串写到代码里面都是一个相对好一些的实践。
NSLocalizedString
最基本的用法如下:
NSLocalizedString("title", comment: "") //输出内容 "主页"
要正常使用 NSLocalizedString
,还需要一个 Localizable.strings
文件。 这个文件中存放的就是字符串键值对:
"title"="主页";
title 对应我们上面的调用的第一个参数。 在运行时 NSLocalizedString
会在这个文件中查找和一个参数匹配的键值,然后读出真正要显示的字符串。
这就是 NSLocalizedString
的基本运作流程了,先准备一个 Localizable.strings
文件,然后调用 NSLocalizedString
方法读取里面的内容,基本内容就说这么多,下面再一起再和大家说说怎么能把它用的更好一些。
随着项目逐渐变大, Localizable.strings
中的字符串键值一定会越来越多。 这就涉及到每个键的命名,如果随意命名,就难免造成混乱,比如:
"home"="主页";
"myhome"="我的主页";
"rate"="给个评价";
"newshome"="新闻主页";
"loadnews"="加载新闻";
//...
一个相对好一些的名称组织方式是使用命名空间:
"main.home"="主页";
"my.home"="我的主页";
"my.rate"="给个评价";
"news.home"="新闻主页";
"news.load"="加载新闻";
这里的命名空间不会有编译层面的检测,只是我们在逻辑上的组织,通过对名称简单的合理组织,对项目的可维护性会有很大的提高。
几个附加参数NSLocalizedString
除了我们开始介绍的传入键名和注释的这个调用方式外:
NSLocalizedString("title", comment: "")
还提供了传入更多参数的版本:
NSLocalizedString(_ key: String, tableName: String?, bundle: Bundle, value: String, comment: String)
可以指定 tableName
参数,用来确定 .strings
的文件名。 默认情况下,系统会从 Main Bundle 中加载名称为 Localizable.strings
的文件。 如果这样调用:
NSLocalizedString("test", tableName: "back.strings", bundle: Bundle.main, value: "", comment: "")
就会在 back.strings
文件中查询,而不是默认的 Localizable.strings
了。
那么 tableName
这个参数有什么实际用处呢? 如果项目规模开始变得比较大,就可以把不同模块的字符串资源分开存放,然后通过 tableName
参数分别加载。
另外除了 tableName
之外,NSLocalizedString
还可以指定 bundle
:
if let bundleURL = Bundle.main.url(forResource: "external", withExtension: "bundle") {
if let extBundle = Bundle(url: bundleURL) {
let str = NSLocalizedString("test", tableName: "table", bundle: extBundle, value: "", comment: "")
print(str)
}
}
上面这段代码,首先加载 external.bundle
, 然后从这个 bundle 里面的 table.strings
文件中查找对应的字符串键值。
这样,除了用文件把字符串分开,还可以把这些文件分散在不同的 Bundle
中。又多了一个维度,对于依赖模块非常多的大项目中,这个机制还是比较有用的。比如不同模块的团队都用同一个键值命名字符串,通过文件和 Bundle 的分离,就可以避免重名冲突。
还记得我们最开始例子中的 comment 参数吧,用作对这个键值的注释,大多数键值名称其实已经基本表示清除含义了,比如:
"news.home"="新闻主页";
"news.load"="加载新闻";
对于这些键值,是否写注释都不妨碍理解。 注释更适合的场景是格式化输出,比如这样:
"%i views"="%i views";
上面这个字符串资源本身又是一个格式化输出模板, 那么我们就可以这样调用:
let format = NSLocalizedString("%i views", comment: "{总浏览量} views")
print(String(format: format, 20))
这里 comment 给每个格式化参数的含义做了注释,这样其他人就能更快的看懂这段代码的含义。
结束这次介绍了 NSLocalizedString
的基本用法,以及它的几个重载参数的应用场景。这几个重载方法对于规模稍大的项目,以及模块化思路都有很好的帮助。还给大家分享了关于注释和键值命名的一些建议。
当然,这一切都不是必须的, 即使你用硬编码的方法把字符串直接写在代码里也不一定就不行。但好的设计思路肯定会让你的开发效率越来越高。同时还推荐给大家一篇 objc.io 的文章,里面有对本地化更详细的介绍 www.objc.io/issues/9-st…
如果你觉得这篇文章有帮助,还可以关注微信公众号 swift-cafe,会有更多我的原创内容分享给你~
本站文章均为原创内容,如需转载请注明出处,谢谢。