【发布时间】:2014-01-30 15:12:16
【问题描述】:
我正在为讲俄语的人开发应用程序。俄罗斯附近的许多国家都有第二语言——俄语。我的应用程序有两种本地化版本:俄语和英语。我需要像默认一样设置俄语本地化。英语应仅适用于使用类似设备语言的英语的人。
我知道 Apple 建议在设置中优先使用首选语言的本地化,但我有一个重要的理由不遵循此建议。
如何将俄语本地化设置为默认设置?
【问题讨论】:
标签: ios objective-c iphone xcode
我正在为讲俄语的人开发应用程序。俄罗斯附近的许多国家都有第二语言——俄语。我的应用程序有两种本地化版本:俄语和英语。我需要像默认一样设置俄语本地化。英语应仅适用于使用类似设备语言的英语的人。
我知道 Apple 建议在设置中优先使用首选语言的本地化,但我有一个重要的理由不遵循此建议。
如何将俄语本地化设置为默认设置?
【问题讨论】:
标签: ios objective-c iphone xcode
我认为您需要在 info.plist 文件中使用 Localization native development region 键。
【讨论】:
您可能需要在 Info.plist 中将俄语设置为 CFBundleDevelopmentRegion 的值。
CFBundleDevelopmentRegion (String - iOS, OS X) 指定包的本地区域。此键包含一个字符串值,该值通常对应于编写包的人的母语。如果无法找到用户首选区域或语言的资源,则使用此值指定的语言作为默认语言。
如果你真的想要并且需要覆盖操作系统的语言优先级,你可以使用AppleLanguages用户默认键(虽然你知道,不推荐这样做):
[[NSUserDefaults standardUserDefaults] setObject:@[@“ru”, @“en”] forKey:@“AppleLanguages”];
【讨论】:
AppleLanguages 键可能有问题。您可能必须很早就设置它,例如在 main() 中。
在我的情况下,我的应用程序中只有带有硬编码字符串的俄语本地化,但我使用带有本地化包的库。库中的字符串默认为英文。因为NSBundle.mainBundle.preferredLanguages 是[ "en" ]。
我在 Info.plist 中使用 CFBundleLocalizations 键指定应用程序本地化语言后,它们变成了俄语:
CFBundleLocalizations (Array - iOS, OS X) 识别本地化 由您的应用手动处理。如果您的可执行文件未捆绑或没有 不使用现有的包本地化机制,您可以包括 此键用于指定您的应用处理的本地化。
此属性数组中的每个条目都是一个字符串,用于标识 支持的语言名称或 ISO 语言指示符 本土化。请参阅“语言和区域设置”中的 国际化与本地化指南 有关如何指定语言指示符的信息的文档。
【讨论】:
我还没有找到合适的解决方案。只有一种适合我的问题的方法是使用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);
否则查找并使用默认捆绑包。
【讨论】:
正如 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()
}
就是这样。如果首选语言不是英语,您将使用俄语作为第一语言替换列表。
附:如果您不仅要进行本地化,还要进行国际化,请不要忘记检查日期选择器、日期格式化程序、数字格式化程序等使用的语言环境。
【讨论】:
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);
}
【讨论】: