如何为 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
第二次覆盖 init
的 UIApplication
子类方法,以自行替换首选语言列表。
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 应用设置默认本地化的主要内容,如果未能解决你的问题,请参考以下文章