iPhone应用本地化 - 英语问题?

18

我有一个应用程序需要翻译成多种不同的语言。问题是,这个应用程序在澳大利亚和新西兰这两个英语国家中会有一些不同的数值。

我已经创建了en_AU和en_NZ的语言文件,但它们仍然使用标准的英语文件。我删除了英语语言文件,但问题仍然存在...

有没有任何想法可以解决这个问题?

谢谢,

--d

5个回答

39

iPhone本地化(或者说本地化)不会考虑用户设置的地区(例如英国、澳大利亚、新西兰等)。默认只提供一个“英语”语言翻译。但是,您可以通过一些技巧来强制使用其他翻译设置 - 我刚刚在选择“英语”(美式英语)和“en_GB”(英式英语)之间做了这个。

在您的main.m文件中,将其更改为以下内容(替换为自己的NZ或AU测试)

int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

// Set up the locale jiggery pokery
NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];
NSString *locale = [[NSLocale currentLocale] objectForKey: NSLocaleCountryCode];
if ([language isEqualToString:@"en"] && [locale isEqualToString:@"GB"]) {
    [[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"en_GB", @"en", nil] forKey:@"AppleLanguages"];
}

int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;

这将把用户的语言(例如“en”)弹出到语言NSString中,并将用户的区域设置(例如NZ,GB,AU)弹出到区域NSString中。 如果它们(在我的情况下)匹配en和GB,则将用户默认语言首选项设置为“en_GB”,然后是“en”。

接下来,在您的应用程序代理的application:didFinishLaunchingWithOptions方法中,您需要使用代码删除刚刚设置的NSUserDefaults设置。

    [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"AppleLanguages"];

此时安全删除该文件,因为所有的捆绑初始化已经完成。您的应用程序现在应该使用位于en_GB.lproj目录中的Localization.strings文件。

这是一个有点可怕和粗糙的解决方案,但它对我有效。


16

我想出了一种稍微改进了rickerbh已被接受答案的版本。首先要意识到的是,用户默认设置是组织成域的,而@"AppleLanguages"关键字不是来自应用程序的域,而是来自域层次结构中更高级别的一些域。这意味着完全可以安全地从用户默认设置中删除它:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:@"AppleLanguages"];
调用此代码后,您会注意到调用[defaults objectForKey:@"AppleLanguages"]仍会返回一个值。因此,与其稍后删除@"AppleLanguages"(这可能会根据应用程序的复杂性而出现问题),您要做相反的操作:立即删除@"AppleLanguages"。这将将其重置回默认值并捕获系统对其所做的任何更改,例如用户已更改其首选语言。以下是我的做法:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:@"AppleLanguages"];

NSMutableArray *appleLanguages = [[defaults objectForKey:@"AppleLanguages"] mutableCopy];
NSString *region = [[NSLocale currentLocale] objectForKey:NSLocaleCountryCode];
NSArray *languages = [appleLanguages filteredArrayUsingPredicateFormat:@"not (self contains '-')"];
for (NSString *language in languages) {
    NSString *languageAndRegion = [NSString stringWithFormat:@"%@-%@", language, region];
    [appleLanguages removeObject:languageAndRegion];
}
for (NSString *language in languages) {
    NSString *languageAndRegion = [NSString stringWithFormat:@"%@-%@", language, region];
    NSInteger index = [appleLanguages indexOfObject:language];
    [appleLanguages insertObject:languageAndRegion atIndex:index];
}
[defaults setObject:appleLanguages forKey:@"AppleLanguages"];

(注意,filteredArrayUsingPredicateFormat:是我编写的扩展方法。弄清它的作用和工作原理并不需要什么高深的技术。)

这将为列表中的每种语言与用户的区域结合创建本地化。例如,如果原始列表是 es en en-GB ,用户的区域为AU,则我们将得到 es-AU es en-AU en en-GB。请注意,es-AU不存在,但这没有任何影响。由于应用程序找不到相关联的本地化或资源,因此它只会忽略它。


1
使用iOS 8.1,这是解决方案。 - Mike
这看起来很稳定。还有一件事要补充,@selector(filteredArrayUsingPredicateFormat:)是NSArray的一个类别方法,你可以在这里找到它:https://github.com/huguesbr/library-ios/blob/master/Categories/NSArray%2BFilteredSortedShortcuts.m - Brian Sachetta
此外,您将此放在代码的哪个位置:在应用程序委托中还是在您的“主”函数中? - Brian Sachetta
1
我把它放在主函数里。当然,这对于Swift项目来说不是一个选项,所以我不确定如何在那里处理它。我从未尝试过在应用程序委托中使用它。也许在那里可以正常工作。不确定。 - Gregory Higley
似乎这也适用于iOS 9,但我们不得不这样做实在是个玩笑。 - Ricky

4

这里是苹果文档中关于iOS缺失功能的说明。

重要提示:在iOS中,当查找本地化资源时,bundle接口不考虑方言或脚本信息;只有语言标识代码会被考虑。因此,如果您的项目包括具有语言和地区标识符的特定语言项目目录,则这些目录将被忽略。Mac OS X中的bundle接口支持语言特定项目目录中的地区标识符。


0
值得注意的是,XCode非常具有误导性 - 您可以转到项目(而不是目标),信息,本地化,在语言列表下方出现的+按钮,然后向下滚动到弹出窗口中出现的语言列表底部,直到您到达“其他”(旁边带有右箭头),这将打开一个包括语言区域变体的大型列表。但是,这些语言区域变体在iPhone上不起作用 - 您什么也得不到(正如苹果公司所记录并在此处提到的另一个答案所引用的)。显然,上面列出的基于代码的解决方案之一是必要的。

0
我在处理德语相关问题时遇到了同样的困扰,但是我认为我已经找到了“正确”的解决方案。我的错误在于最初我的基础语言只是“German (de)”,当我添加“German/Austria (de_AT)”本地化时,文件被忽略了。当我更改基础语言为“German/Germany (de_DE)”时,奥地利的翻译就不再被忽视了。

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