摘要
Apple 提供了很棒的国际化本地化工具(参见官方文档)。然而,有些痛点并不是很容易得到解决
- 大量的 .strings 文件需要维护:`genstrings` 会从代码中提取 `NSLocalizedString` 字符串,但对于您希望国际化的每个 IB 文档,您需要一个单独的 .strings 文件,这导致了本地化字符串的痛苦维护。此外,如果您已经在几个文件中本地化了常见的表达式,您需要记住单独更新每个文件。
- 本地化新版本非常痛苦:当您在 IB 中更改视图时,其 .strings 文件可能立即变得无效,而且很难利用之前的版本中已有的本地化。这也适用于通过 `genstrings` 提取的 .strings。
- NSLocalizedString 假设字符串在主 bundle 中:如果您想使用其他本地化 bundle 路径(例如在运行时从服务器下载的一些文件的路径),您需要使用更复杂的宏。
- NSLocalizedString 会自动确定要使用的区域设置:这是很好的,但通常用户想更改应用程序的这项首选项,而不需要改变整个设备的语言。
JTLocalize 就是用来解决这些痛点的
- 统一 .strings 文件:收集项目中多个类型的资源中的多个可本地化字符串。对于每个 storyboard/xib 无需单独的字符串文件 - 只需维护一个文件,且不会存在重复的字符串。
- 简化了持续的本地化集成:当应用程序发生变化时,您不需要重新本地化所有内容。`jtlocalize` 命令行工具将使您可以轻松地仅发送需要翻译的 diff,并将翻译后的 diff 合并回来。
- 可配置的本地化 bundle 位置:这允许您轻松决定使用主 bundle 作为默认值,并且一旦从服务器下载,可以轻松转移到另一个路径。作为一个副作用,您可以轻松使用 JTLocalize 来更改您从服务器下载的所有字符串的英文版本。
- 可配置首选区域设置:这允许您轻松地让用户选择语言,而不仅仅是依赖于从设备设置中获取的语言。
如何国际化(为统一的(strings)文件准备项目字符串)
国际化是通过自定义Objective-C类和简单的标记机制来完成的。
将内容添加到项目中
JTLocalize 可以通过 CocoaPods 添加到 Xcode 项目中。
pod "JTLocalize"
国际化UI元素
UI元素的国际化适用于xibs和storyboard文件。
为了国际化UI元素(如 UIBotton
、UILabel
、UITextField
等)
-
将JTLocalize框架中相应的类(如
JTButton
、JTLabel
、JTTextField
等)作为UI元素的自定义类。这些类在设置文本时使用适当的本地化字符串。 -
在Interface Builder的文档大纲中,将元素的“userLabel”(文档-》标签)设置为具有
JTL_
前缀的字符串。此前缀受到我们本地化命令行工具字符串提取的尊重。userLabel中剩余的字符串(在JTL_
前缀之后)将被用作本地化字符串条目中Localizable.strings文件的注释。
国际化 DTCoreText 富文本标签
有关国际化 DTCoreText
元素(如DTAttributedLabel
)的说明,请参见示例项目中的插图(DTAttributedLabel+JTLocalizeExtensions,JTAttributedLabelWithLink)。将其仅包含在示例项目中是为了避免在 Pod 中包含 DTCoreText
依赖项。
如果您想使用它们(并对其进行国际化),请添加一个命名为 htmlString 的密钥路径,带有包含 html 字符串的值。在这个 html 字符串值中,只需在放置本地化字符串值的地方放置 JTL("Key", "Comment")
。
在代码中本地化字符串
要本地化代码中的字符串,只需简单地使用JTLocalizedString()宏(就像您通常使用NSLocalizedString()一样,但使用不同的宏)。
NSString *localizedString = JTLocalizedString("Some string", "The Strings context for translation")
Swift
Swift不支持C宏。我们目前没有将任何Swift函数插入到Pod中,因为CocoaPods的Swift支持仍然处于测试阶段(截至撰写这些内容时)。
相反,我们附上了我们的示例项目的POC,以向您展示如何轻松地在Swift项目中使用JTLocalize
。请参阅JTSwiftPOC.swift
如何本地化
JTLocalize框架提供了一个与国际化机制集成的jtlocalize
命令行工具,简化了本地化流程。
安装
此应用程序需要
使用pip install jtlocalize
安装,或下载最新发布版本
标准本地化流程
通常我们将使用 ju Jiangtang 实用程序的以下子操作:generate
、prepare_diff
和 merge
:
- 请确保您的
JTLocalizable.bundle
已经准备好包含所需所有语言的目录(更多信息请见附录) - 运行
jtlocalize generate /path/to/project /path/to/JTLocalizable.bundle
- 运行
jtlocalize prepare_diff /path/to/JTLocalizable.bundle
- 将不同语言的目录下的
Localizable.strings.pending
文件进行翻译
(如果需要,转换为编码,参见附录)。 - 将翻译后的文件保存到正确的语言目录下的
Localizable.strings.translated
(如果需要,转换为编码,参见附录)。 - 运行
jtlocalize merge /path/to/JTLocalizable.bundle
mock_translate
另一个有用的子操作,可以帮助您确保您的应用程序中没有国际化任何字符串。
示例用法
jtlocalize mock_translate --preset chicken /path/to/Localizable.strings
将给定的文件本地化为所有翻译均为 "Chicken"。
word_count
通常我们需要将待翻译的字符串文件发送给第三方翻译服务,这些服务按照单词数收费。要得到需要实际翻译的单词的精确字数,可以运行:jtlocalize word_count /path/to/Localizable.strings.pending
更多操作和标志
jtlocalize
支持许多标志和功能,可配置您的本地化流程。您可以通过运行 jtlocalize --help
或 jtlocalize OPERATION --help
以获得有关所有标志的信息。
更新本地化包和运行时首选区域设置
如上所述,我们希望能够轻松地将本地化包从主应用包中移除,以支持从远程服务器更新包的使用场景(作为一个令人惊叹的副作用 - 允许我们更改英文字符串而无需发布新版本!)。我们还希望允许用户更改首选语言。
默认情况下,应用将搜索包含在应用包中的本地化版本 Localizable.strings
在 JTLocalizable.bundle
中(见附录)。此外,默认情况下,应用将根据用户在 iOS 设置应用中的偏好选择首选语言。
要更改此行为,您可以按以下方式更改路径:
[JTLocalize setLocalizationBundleToPath:NEW_PATH stringsTableName:NEW_TABLE_NAME preferredLocale:NEW_LOCALE_IDENTIFIER];
您可以将 nil
作为 NEW_PATH
,NEW_TABLE_NAME
或 NEW_LOCALE_IDENTIFIER
传递,以便使用默认值(应用包,"Localizable"
,以及 iOS 默认决定的可用位置的语言)
NEW_LOCALE_IDENTIFIER
应采用 ISO 639-1 代码的形式(例如 'en','fr','zh-Hans','pt-PT' 等),并实际上将应用重定向到从本地化包中对应的 .lproj 子目录获取字符串表。如果想在应用中任何位置了解 JTLocalize 正在使用哪个语言,可以使用
[JTLocalize effectiveLocale]
在 JoyTunes 公司,我们默认使用 JTLocalizable.bundle
的包版本。当应用加载时,我们将其更新版本从服务器下载到 Documents 目录,并使用下载到的路径调用 setLocalizationBundleToPath
。此外,默认情况下,我们设置首选语言为 nil
,但一旦用户从设置屏幕决定更改此设置,我们就使用更新选择调用此方法,并使用 NSUserDefaults
缓存以供下一次会话使用。
请注意,NSBundle
会自动缓存,因此如果不更改路径就调用此方法,即使内容已更改,也不会刷新包的内容(但会替换首选语言)。
附录
JTLocalizable.bundle - 本地化包
本地化包包含应用本地化为的语言的不同语言的字符串文件。
例如
JTLocalizable.bundle
| +-- en.lproj
| | +-- Localizable.strings
| +-- ru.lproj
| | +-- Localizable.strings
命令行工具 jtlocalize
假设 en.lproj 是默认语言目录(将来可配置)。每次需要添加新语言时,只需确保在运行 prepare_diff
之前向捆绑包中添加一个空的 LANGUAGE_CODE.lproj 目录即可。
将 Localizable.strings 从/to 正确编码转换
注意:Localizable.strings 编码为 UTF16,小端,行结束符设置为 LF。
不同的脚本以这种编码期望并生成文件。
您可以使用
iconv -f utf-8 -t utf-16 Localizable.strings > Localizable.new.strings
将 utf-8 文件转换为我们在脚本中使用的格式。
iconv -f utf-16 -t utf-8 Localizable.strings > Localizable.new.strings
以达到相反的效果。