如何为 iOS 应用设置默认本地化

Posted

技术标签:

【中文标题】如何为 iOS 应用设置默认本地化【英文标题】:How to set default localization for iOS app 【发布时间】:2014-01-30 15:12:16 【问题描述】:

我正在为讲俄语的人开发应用程序。俄罗斯附近的许多国家都有第二语言——俄语。我的应用程序有两种本地化版本:俄语和英语。我需要像默认一样设置俄语本地化。英语应仅适用于使用类似设备语言的英语的人。

我知道 Apple 建议在设置中优先使用首选语言的本地化,但我有一个重要的理由不遵循此建议。

如何将俄语本地化设置为默认设置?

【问题讨论】:

【参考方案1】:

我认为您需要在 info.plist 文件中使用 Localization native development region 键。

【讨论】:

这就是答案! @hasan83 不适合我。你能提出一个解决方案吗?【参考方案2】:

您可能需要在 Info.plist 中将俄语设置为 CFBundleDevelopmentRegion 的值。

CFBundleDevelopmentRegion (String - ios, OS X) 指定包的本地区域。此键包含一个字符串值,该值通常对应于编写包的人的母语。如果无法找到用户首选区域或语言的资源,则使用此值指定的语言作为默认语言。

更新

如果你真的想要并且需要覆盖操作系统的语言优先级,你可以使用AppleLanguages用户默认键(虽然你知道,不推荐这样做):

[[NSUserDefaults standardUserDefaults] setObject:@[@“ru”, @“en”] forKey:@“AppleLanguages”];

【讨论】:

我试过这样做,但没有结果。如果你按下 Info.plist 中 CFBundleDevelopmentRegion 字段的值,你可以看到 XCode 只为这个参数建议了 11 种语言。我尝试手动输入“ru”但没有结果。 您的应用程序有俄语和英语本地化,并且此键设置为 ru,对吗?然后你选择其他语言,比如西班牙语,UI 还是英文?我注意到至少在 iOS 7 中,操作系统会考虑系统偏好中语言的顺序。因此,如果您在英语之后切换到西班牙语,则顺序将是西班牙语、英语、俄语,而应用程序将是英语的。检查是否是这种情况。例如,在俄语之后切换到不支持的语言。 是的,如果订单是:西班牙语、俄语、英语 - 那么应用程序使用俄语。但是例如在乌克兰,很多人在购买 iPhone 后首先选择乌克兰语,并且永远不会更改语言顺序。在这种情况下,乌克兰用户按顺序排列第二项 - 英语。 设置AppleLanguages 键可能有问题。您可能必须很早就设置它,例如在 main() 中。 这个问题已经 6 年了,Apple 没有解决这个问题。【参考方案3】:

在我的情况下,我的应用程序中只有带有硬编码字符串的俄语本地化,但我使用带有本地化包的库。库中的字符串默认为英文。因为NSBundle.mainBundle.preferredLanguages[ "en" ]

我在 Info.plist 中使用 CFBundleLocalizations 键指定应用程序本地化语言后,它们变成了俄语:

CFBundleLocalizations (Array - iOS, OS X) 识别本地化 由您的应用手动处理。如果您的可执行文件未捆绑或没有 不使用现有的包本地化机制,您可以包括 此键用于指定您的应用处理的本地化。

此属性数组中的每个条目都是一个字符串,用于标识 支持的语言名称或 ISO 语言指示符 本土化。请参阅“语言和区域设置”中的 国际化与本地化指南 有关如何指定语言指示符的信息的文档。

【讨论】:

【参考方案4】:

我还没有找到合适的解决方案。只有一种适合我的问题的方法是使用NSLocalizedStringFromTableInBundle 而不是NSLocalizedString。这种方式不允许本地化图像或笔尖,但使用字符串时效果很好。

首先你需要定义当前的设备语言:

NSString *lang = (NSString *)[[NSLocale preferredLanguages] objectAtIndex:0];

接下来找到该语言的捆绑包:

NSBundle *myLangBundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:lang ofType:@"lproj"]];

如果找到捆绑包,则在 NSLocalizedStringFromTableInBundle 中使用它:

_label.text = NSLocalizedStringFromTableInBundle(@"LabelText",nil,myLangBundle,nil);

否则查找并使用默认捆绑包。

【讨论】:

【参考方案5】:

正如 eofster 所说,您应该将 AppleLanguages 中的 NSUserDefaults 键设置为具有所需顺序的语言数组,但是为了在第一次午餐时工作,您应该很早就开始工作,甚至早于applicationWillLunchWithOptions:

对我来说,这个解决方案效果很好,并且在使用 NSLocalizedStringFromTableInBundle 时具有优势,因为它也适用于故事板和笔尖。

这里是关于 Swift 语言的分步解决方案。

    如下所述创建 UIApplication 的子类:Subclass UIApplication with Swift

    第二次覆盖 initUIApplication 子类方法,以自行替换首选语言列表。

    override init() 
        if let languages = NSUserDefaults.standardUserDefaults().objectForKey("AppleLanguages") as? [String],
            let language = languages.first where !language.hasPrefix("en")
        
            NSUserDefaults.standardUserDefaults().setObject(["ru", "en"], forKey: "AppleLanguages")
        
    
        super.init()
    
    

    斯威夫特 4:

    override init() 
    if let languages = UserDefaults.standard.object(forKey: "AppleLanguages") as? [String],
        let language = languages.first(where:!$0.hasPrefix("en"))
    
        UserDefaults.standard.set(["ru", "en"], forKey: "AppleLanguages")
    
    
    super.init()
    

    就是这样。如果首选语言不是英语,您将使用俄语作为第一语言替换列表。

附:如果您不仅要进行本地化,还要进行国际化,请不要忘记检查日期选择器、日期格式化程序、数字格式化程序等使用的语言环境。

【讨论】:

【参考方案6】:

preferredLanguages 有时会返回“ru_RU”,但我的 lproj 是 ru.lproj。所以我决定另一种解决方案。 我将 "test.lang.phrase = "YES"; 添加到所有可本地化的字符串文件中。如果找不到本地化,我会加载默认本地化。

NSString *result = nil;
NSString *testLang = NSLocalizedString(@"test.lang.phrase", nil);
if ([testLang isEqualToString:@"YES"]) 
    result = NSLocalizedString(str, nil);

if (!result) 
    NSBundle *myLangBundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"]];
    result = NSLocalizedStringFromTableInBundle(str, nil, myLangBundle,nil);

【讨论】:

以上是关于如何为 iOS 应用设置默认本地化的主要内容,如果未能解决你的问题,请参考以下文章

如何为 Apple Watch 配置本地通知

如何为整个 c# 应用程序设置默认文化信息

如何为本地化应用加载 XIB?

如何为本地安装 npm 包设置自定义位置?

如何为编码的 UI 测试设置文化以从资源文件中获取本地化文本?

如何为本地主机测试运行设置虚拟目录?