我有一个相当复杂的项目,包括几个大型的本地化子项目.
我的大多数子项目都是通过一个Localizable.strings文件进行本地化的.此文件将复制到SubProjectName.bundle目标中,该目标与主项目中的SubProjectName.a静态库一起使用.这很好用.
但是,我的一个子项目包含许多本地化的.strings文件.无论设备(或模拟器)的配置方式如何,此项目都无法读取除英语之外的任何语言的字符串.
[[NSBundle myResourcesBundle] localizedStringForKey:@"MY_TEST_STRING" value:@"" table:@"MyTable"]
MyTable对应于本地化为多种语言的MyTable.strings文件.当我查看.app包时,所有本地化都在那里,位于应用程序内的“MyBundle.bundle”资源中.
但是,以下代码在所有本地化中正确查找给定字符串的翻译:
for (NSString *language in [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleLanguages"]) { NSBundle *bundle = [NSBundle bundleWithPath:[[NSBundle myResourcesBundle] pathForResource:language ofType:@"lproj"]]; NSLog(@"%@: %@",language,NSLocalizedStringFromTableInBundle(@"MY_TEST_STRING",@"MyTable",bundle,nil)); }
因此,当bundle是实际的MyBundle.bundle /< LanguageCode> .lproj文件夹时,字符串查找起作用.但显然这违背了iOS提供的自动查找的目的.
(注意,上面的[NSBundle myResourcesBundle]只是一个静态便捷方法,用于获取子项目的自定义包).
–
编辑:我一直在尝试这个,如果我从子项目的包中删除en.lproj文件夹,那么它正确使用设备或模拟器的区域设置.
例如,我有:
MyApp.app/ | - MyResources.bundle/ | - en.lproj/ | - zh-Hans.lproj/
当我将模拟器(或设备)设置为简体中文时,它会在en.lproj中查找字符串,即使语言环境是zh-Hans.如果我删除en.lproj文件夹并重新启动应用程序,它会正确使用zh-Hans本地化.
解决方法
我能够重现并修复问题,虽然解决方案确实意味着NSBundle中存在一个错误.
我使用以下捆绑结构复制它:
MyApp.app/ | - MyResources.bundle/ | - en.lproj/ | - fr.lproj/
和代码:
NSLog(@"A key: %@",NSLocalizedString(@"A key",nil)); NSBundle *bundle = [NSBundle bundleWithPath: [[NSBundle mainBundle] pathForResource: @"MyResources" ofType: @"bundle"]]; NSLog(@"Current locale: %@",[[NSLocale currentLocale] localeIdentifier]); NSLog(@"Bundle localizations: %@",[bundle localizations]); NSLog(@"Key from bundle: %@",[bundle localizedStringForKey: @"A key" value: @"Can't find it." table: nil]); NSLog(@"Key using bundle macro: %@",NSLocalizedStringFromTableInBundle(@"A key",nil,nil));
将语言环境设置为fr_FR(即法语)时,该包从英语字符串表中选取字符串 – 即使字符串“找不到它”也不会出现.
MyApp.app/ | - MyResources.bundle/ | - Resources/ | - en.lproj/ | - fr.lproj/
看起来NSBundle仍然期望旧的Mac OS X捆绑结构而不是iOS应该使用的.因此,简单的束结构更改应该可以解决问题……