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

22
我正在为说俄语的人开发应用程序。许多靠近俄罗斯的国家有第二种语言-俄语。我的应用程序有两种本地化:俄语和英语。我需要将俄语本地化设置为默认值。英语应该只针对使用英语作为设备语言的用户。
我知道苹果建议使用首选语言设置中的本地化,但我有一个重要的原因不遵循此建议。
如何将俄语本地化设置为默认值?
6个回答

33
我认为您需要在您的info.plist文件中使用Localization native development region关键字。请参考这里的文档。

6
这就是答案! - hasan
1
@hasan83 对我不起作用。你能否提供一个解决方案? - mars

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

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

更新

如果你真的想要和需要覆盖操作系统的语言优先级,你可以使用 AppleLanguages 用户默认键(尽管,如你所知,这不被推荐):

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

我曾尝试过这个,但是没有结果。如果您在Info.plist中按下CFBundleDevelopmentRegion字段的值,您会发现XCode仅为此参数提供11种语言。我尝试手动输入“ru”但是没有结果。 - 12pm
你的应用程序有俄语和英语本地化,而且这个键是设置为ru的,对吗?然后你选择其他语言,比如西班牙语,但UI仍然是英语?我注意到至少在iOS 7中,操作系统会考虑系统偏好设置中语言的顺序。所以如果你在英语之后切换到西班牙语,顺序将是西班牙语、英语、俄语,应用程序将是英语。请检查是否是这种情况。例如,在俄语之后切换到不支持的语言。 - eofster
是的,如果语言排序为:西班牙语、俄语、英语——则应用程序使用俄语。但是例如在乌克兰,很多人购买了iPhone之后首选选择乌克兰语,并且从未更改过语言顺序。在这种情况下,乌克兰用户的语言顺序是第二项-英语。 - 12pm
2
设置AppleLanguages键可能会出现问题。您可能需要非常早地设置它,例如在main()函数中。 - eofster
3
这个问题已经存在6年了,但苹果一直没有解决。 - Duck
显示剩余2条评论

5
在我的情况下,我的应用程序只有俄语本地化,并且使用具有本地化包的库。 库中的字符串默认为英语。 这是由于 NSBundle.mainBundle.preferredLanguages 为 [ "en"] 。 在我使用 CFBundleLocalizations 键指定应用程序本地化语言之后,它们变成了俄语。

screenshot

CFBundleLocalizations(数组 - iOS、OS X)标识了您的应用程序手动处理的本地化。如果您的可执行文件未捆绑或不使用现有的包本地化机制,则可以包含此键以指定您的应用程序处理的本地化。该属性数组中的每个条目都是一个字符串,用于标识受支持的本地化的语言名称或 ISO 语言代码。有关如何指定语言代码的信息,请参阅国际化和本地化指南中的“语言和区域设置指定”部分的国际化文档。

4
如eofster所说,您应该在NSUserDefaults中将AppleLanguages键设置为带有所需顺序的语言数组,但是要使其在第一次启动时起作用,您应该尽早完成它,甚至比applicationWillLunchWithOptions更早。
对我而言,这个解决方案非常好,并且比使用NSLocalizedStringFromTableInBundle具有优势,因为它也适用于storyboards和nibs。
以下是Swift语言的逐步解决方案。
  1. Make subclass of UIApplication as described here: Subclass UIApplication with Swift

  2. Second override init method of you UIApplication subclass to substitute list of preferred languages on your own.

    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()
    }
    

    Swift 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()
    

    }

  3. That's all. If first preferred language is not English you'll substitute list with Russian as first language.

顺便提一句,如果你不仅仅是进行本地化工作,还要进行国际化,请注意检查所使用的日期选取器、日期格式化程序、数字格式化程序等所使用的语言环境。


4

我还没有找到合适的解决方案。唯一适用于我的问题的方法是使用NSLocalizedStringFromTableInBundle替代NSLocalizedString。虽然这种方法不允许本地化图像或nibs文件,但对于字符串来说效果非常好。

首先,您需要定义当前设备语言:

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

接下来找到该语言的包:

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

如果找到bundle,则在NSLocalizedStringFromTableInBundle中使用它:
_label.text = NSLocalizedStringFromTableInBundle(@"LabelText",nil,myLangBundle,nil);

否则查找并使用默认包。

0

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);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接