Swift 4.2中可枚举的可本地化键
首先,在iOS应用程序中本地化内容似乎很容易。 NSLocalizedString
如果支持多种语言,API将在纯文本Localizable.string文件中查找给定键的转换值。
但是,这种机制很容易导致显影剂出错。 随着项目的发展,复杂性会增加:要支持的新语言环境,数百个新密钥,或者更改捆绑资源结构的不同且更复杂的构建过程可能会由于缺少翻译或更糟糕的副本而导致应用程序回归。
理想情况下,开发人员应仅使用在所有支持的语言环境中均已转换了其值的键,并且应确保在编译时发现本地化机制的最终损坏(丢失资源,格式错误,错误的键删除等),这是安全的。通过单元测试。
罪魁祸首是在NSLocalizedString
键和Localizable.string文件中操纵原始字符串。 实际上,使用原始原始Strings缺乏编译时类型安全检查的优势。
解决此问题的一种方法是实现不透明类型,以表示可本地化的String,该String内部使用包含所有受支持键的String enum
:
这将解决一半的问题,但是如何保证可本地化文件未损坏或在所有语言环境中都提供了有效的字符串呢?
CaseIterable进行救援的枚举
Swift 4.2中引入的枚举中的CaseIterable
协议一致性使得枚举可以枚举枚举中所有已定义的var allKeys: [EnumType] = [.case2, .case2, …]
而无需手动实现所有键的数组(不再有var allKeys: [EnumType] = [.case2, .case2, …]
!🎊)。
通过使LocaleKey
与CaseIterable
,可以编写一个简单但有效的单元测试,该单元测试将遍历每种情况,以检查LocalizedText
是否提供了转换后的值而不是返回键本身:
这将标记缺少的翻译,并防止意外错误在开发分支中合并。
多个地区
可以扩展LocalizedText
结构以支持特定tableNames
的注入,以便检查是否为每个语言环境提供了翻译:
然后, LocaleKeyTests
单元测试可以检查所有支持的语言环境是否配置正确:
GitHub上的示例项目中包含一个使用LanguageTableProvider的更广泛的示例:https://github.com/matsoftware/LocaleEnumerable
结论
CaseIterable
枚举协议一致性的实现是真正的类型安全语言的发展中的重要一步。 String的本地化只是最简单的方案之一,其应用程序将通过连续集成中的简单单元测试来帮助减少人为错误的影响,从而减少时间和挫败感。
请在LinkedIn上关注我:https://www.linkedin.com/in/matcamp/