为什么我的iOS应用程序仅在首次运行时正确检测当前语言?

Mas*_*iti 25 localization ios xcode4

我正在本地化我的iOS应用程序,并且在模拟器中它每次都以我选择的语言正确运行.

在我的iPhone 5上进行测试时,它只会在应用首次运行时正确检测语言.每次我在设备上重新编译并运行我的应用程序时,它会检测到"en"作为语言,即使我选择了Español("es")进行测试.

我使用以下方法检测语言:

[[[NSBundle mainBundle] preferredLocalizations] objectAtIndex:0]

我也用过:

[[NSLocale preferredLanguages] objectAtIndex:0]

结果相同.

如果我在第一次运行后终止应用程序,并在设备上重新启动它,它会继续正确检测语言.

但是如果我杀死应用程序然后在初始运行后通过Xcode重新编译/重新启动,它将加载"en"(英语)而不是检测到.

之后,杀死并重新启动应用程序会持续检测为英语,除非我完全删除应用程序,并通过Xcode重新编译/重新安装/运行应用程序.然后循环重复...后续重建/重启而不首先从设备中删除应用程序导致错误检测.

我的设备上的所有其他应用程序一直显示西班牙语.整个UI以西班牙语显示.

更新:我现在已经在运行iOS 6的iPad(第3代)上进行了测试,并且遇到了相同的行为.

更新2:

在didFinishLaunchingWithOptions中,我有这个代码来检测语言:(语言是NSString*):

language = [[NSLocale preferredLanguages] objectAtIndex:0];

接下来是这个调试语句,比较我得到的值,以及稍微不同的检测方式,仅用于调试:

NSLog(@"Detected language: %@ / %@", language, [[[NSBundle mainBundle] preferredLocalizations] objectAtIndex:0]);

当应用程序在西班牙语模式下正常工作时,输出显示为"检测到的语言:es/es",然后显示为"检测到的语言:en/en".仍然不知道为什么它决定加载为英语有时......

更新4:我感谢大家的答案,我尝试了各种建议.不幸的是,我无法奖励+100赏金,因为没有任何建议似乎解决了这个问题.如果某人确实找到了适合我的解决方案,那么我将在那时再向他们奖励+50赏金.

更新5:我已经从Xcode 4.5更新到4.5.2,并遇到了同样的问题.

更新6:我现在已经从头开始创建了一个新的测试项目,它工作得很好!显然,我的项目布局方式或者可能是其中一个数据文件中的某些内容必定是错误的.我想我的下一个旅程将是从头开始重新创建项目,逐个复制文件数据......

更新7(稍后):可悲的是,在通过精心重建我的项目暂时解决(看似)之后,我再次面临这个问题.在第一次加载时,语言被正确呈现,但在后续加载时,它将恢复为英语.

已解决请参阅下面的最终解决方案.感谢大家的帮助.我可能会拿出一些赏金,因为无论如何它都会浪费掉.

Mas*_*iti 8

几个月后我终于彻底解决了这个问题!感谢所有人的帮助(我也通过开发渠道与Apple开发人员进行了一些良好的反复).

TL; DR:我使用我的应用程序的iCloud密钥值存储(通过MKiCloudSync)意外地在设备之间同步语言首选项(以及许多其他意想不到的事物)!继续阅读......

我正在使用名为MKiCloudSync的第三方类,它有助于同步[NSUserDefaults standardUserDefaults]到我的应用程序的iCloud密钥值存储区.我开始使用它的目的是让它在后台处理一些用户收藏夹同步.

然而,不理解如何standardUserDefaults工作,我没有意识到的是,standardUserDefaults除了我自己的自定义应用程序设置之外,还有很多其他的东西被写入!

所以发生了什么是这样的:

  1. 第一次启动应用程序.新鲜standardUserDefaults到位,并且存储有序语言首选项列表的内部"AppleLanguages"键基于当前设备选择是正确的.

  2. 应用程序以指定语言正确显示.

  3. 在后台,MKiCloudSync同步ALL standardUserDefaults到iCloud.相反,如果您在其他地方运行此应用程序,例如使用英语设置设备,该设备也会将其语言设置同步到iCloud.所以现在这个当前运行的应用程序实际上已经覆盖了它的语言首选项.

  4. BOOM ......下次运行应用程序时,无论您在设备上选择了什么,它都是从iCloud中下载的任何内容,它将被用作默认语言!

我计划用下一个应用更新来解决问题:

  1. 使用分叉版本的MKiCloudSync,它只允许同步列入白名单的密钥名称.

  2. 添加将进行一次性清理的代码,首先清理我的应用程序的iCloud密钥库,然后(基于此SO答案),调用此代码重置用户默认值:

    NSString*appDomain = [[NSBundle mainBundle] bundleIdentifier]; [[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];

在我的测试,到目前为止,这种解决问题......不幸的是,用户将不得不重新启动的语言修复踢的应用程序.但是,我的猜测是大多数用户不会遇到这个问题,因为他们不可能使用具有不同默认语言的多个设备.