在开发iOS应用时,我们可能会遇到需要使用不同语言的字符串资源的情况。比如,当iOS的语言设置为A,而我们的应用需要使用语言B。 这里有一个语音计算器,用户可以在计算时选择不同的语音朗读语言,而无需改变整个iOS的语言设置。例如,如果我们的手机语言设置为英语,但我们希望计算器能用中文朗读计算结果。

为了实现这个功能,我们可以使用iOS的本地化机制。有两种常见的解决方案:

  1. 加载相应语言的资源文件

我们可以为每种语言创建一个资源文件,并在其中添加我们的本地化字符串。然后,我们可以根据用户选择的语言,从相应的资源文件中加载字符串。

在Swift中,我们可以使用如下方式实现:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
extension String {
    var localized: String {
        // TalkingNumCalUserDefaults.voiceLang has value like 'en-US', 'fr-FR', 'de-DE' etc.
        if let lang = Locale(identifier: TalkingNumCalUserDefaults.voiceLang).languageCode { // e.g. en, jp, zh ...
            if let path = Bundle.main.path(forResource: lang, ofType: "lproj"), let bundle = Bundle(path: path) {
                let string = bundle.localizedString(forKey: self, value: nil, table: nil)
                return string
            }
        }
        return NSLocalizedString(self, comment: "")
    }
}

这个解决方案需要我们预先准备好所有可能用到的语言的资源文件。当用户选择了一种语言后,我们从对应的资源文件中加载字符串。如果没有找到对应的资源文件,我们就返回一个未本地化的字符串。

  1. 设置Bundle的语言

我们可以先通过用户选择的语言设置Bundle的语言,然后直接从Bundle中获取本地化的字符串。

在Swift中,我们可以使用如下方式实现:

1
2
3
4
5
6
7
8
9
extension String {
    var localized: String {
        // TalkingNumCalUserDefaults.voiceLang has value like 'en-US', 'fr-FR', 'de-DE' etc.
        if let lang = Locale(identifier: TalkingNumCalUserDefaults.voiceLang).languageCode { // e.g. en, jp, zh ...
            Bundle.setLanguage(lang)
        }
        return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
    }
}

这个解决方案需要我们在每次用户选择一种新的语言时,都重新设置一次Bundle的语言。然后,我们从Bundle中获取本地化的字符串。如果没有找到对应的字符串,我们就返回一个未本地化的字符串。