【问题标题】:Getting "real" locale used by MacOS获取 MacOS 使用的“真实”语言环境
【发布时间】:2020-05-15 17:28:40
【问题描述】:

我制作了一个 MacOS 应用程序,用户可以在其中选择他想要在应用程序中使用的语言。

要在按钮中设置本地化标题,我这样做:

NSLocalizedString("CONTEXT_MENU_OPT_QUIT", bundle: myClass.localeBundle, comment: "Context menu option");

我在启动时运行这段代码来设置localeBundle

    func getLocale() -> String {
        let availableLanguages: [String] = Bundle.main.localizations;
        var locale: String = userDefaults!.string(forKey: "locale") ?? "";

        if (locale.isEmpty) {
            let preferredLocale: String = Locale.preferredLanguages.first!;

            if (availableLanguages.contains(preferredLocale) == false) {
                locale = "en";
            }
        }
        return locale;
    }

    func loadLocale() {
        let currentLocale: String = self.getLocale();
        var bundlePath: String;

        bundlePath = Bundle.main.path(forResource: currentLocale, ofType: "lproj")!;
        myClass.localeBundle = Bundle.init(path: bundlePath)!;
    }

这适用于大多数人,但如果系统语言设置与预期区域不同,这将失败。例如:

语言为葡萄牙语,区域设置为俄罗斯:Locale.preferredLanguages.first! 将返回 pt-RU

考虑到我只有pt-PTpt-BR 的翻译,我拥有的代码将默认为“en”,因为“pt-RU”不存在。

我如何获得独立于用户区域的pt-PTpt-BR

谢谢

【问题讨论】:

    标签: swift macos cocoa


    【解决方案1】:

    用户的首选语言设置(在系统偏好设置中设置)存储在“AppleLanguages”键下的用户默认设置中。它是一组语言标识符字符串(如“pt-BR”)。

    用户的设置位于全局域中,但与所有用户默认设置一样,您可以在更多本地域中覆盖该设置。特别是,您可以在应用程序域中设置它以仅影响您的应用程序。

    所以,我认为您应该只在“AppleLanguages”键下存储用户为您的应用程序选择的语言标识符的数组,然后让系统执行它的操作。您不应该尝试自己重现资源搜索算法。

    如果您想继续使用您的技术,可以使用 localization properties and methodsBundle 根据首选本地化列表选择捆绑包中可用的实际本地化之一。也就是说,不要查询localizations,然后检查它是否包含您的语言环境标识符;使用preferredLocalizations(from:forPreferences:) 为您进行搜索。它可能使用更复杂的算法。此外,请记住区域设置和语言之间的区别,尤其是区域设置 ID 与语言 ID。它们代表不同的事物并具有不同的形式,但您似乎可以互换使用它们。

    【讨论】:

    • 不确定我是否遗漏了什么,我设置了一个新的虚拟机,主要语言设置为法语,区域设置为俄罗斯。还添加了更多语言。 UserDefaults.standard.array(forKey: "AppleLanguages") 返回了这个:["fr-RU", "pt-RU", "en-RU"]Bundle.preferredLocalizations(from: UserDefaults.standard.array(forKey: "AppleLanguages") as! [String]) 返回了这个:fr-RU。我希望它返回fr,因为这是我在捆绑包中拥有的最接近的语言环境
    • Bundle.preferredLocalizations(from:) 是一个类方法。也就是说,它并不特定于任何特定的捆绑包,甚至不是主捆绑包。它会获取您提供的本地化列表并选择最接近用户偏好的本地化列表。由于您只是传递用户首选项,因此除了返回第一个之外,它没有理由做任何事情。如果您想遵守用户偏好,您可以查看Bundle.main.preferredLocalizations。如果你想使用自定义的内部偏好,你可以使用Bundle.preferredLocalizations(from:… forPreferences:…)
    • 非常感谢肯。很清楚的解释。我完全错过了它是一个类方法,我以为它正在检查主包。
    猜你喜欢
    • 2016-12-09
    • 1970-01-01
    • 2018-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多