iOS App Bundle中的多个本地化.strings文件 [英] Multiple Localized .strings Files in iOS App Bundle
问题描述
我有一个相当复杂的项目,包括几个大型本地化子项目。
I have a fairly complicated project, consisting of several large localized sub-projects.
我的大多数子项目都通过单个 Localizable进行本地化。字符串文件。此文件被复制到 SubProjectName.bundle
目标,该目标与 SubProjectName.a
静态库一起使用主要项目。这很好。
Most of my sub-projects are localized through a single Localizable.strings file. This file is copied into a SubProjectName.bundle
target, which is used in conjunction with a SubProjectName.a
static library in the main project. This works fine.
但是,我的一个子项目包含许多本地化的.strings文件。 无论设备(或模拟器)的配置如何,此项目都无法读取英语以外的任何语言的字符串。
However, one of my sub-projects contains many localized .strings files. This project fails to read strings in any language other than English, regardless of how the device (or simulator) is configured.
例如,这行代码总是返回英文字符串:
For example, this line of code always returns the English string:
[[NSBundle myResourcesBundle] localizedStringForKey:@"MY_TEST_STRING" value:@"" table:@"MyTable"]
其中 MyTable
对应于本地化为多种语言的MyTable.strings文件。当我查看.app包时,所有本地化都在那里,位于应用程序内的MyBundle.bundle资源中。
Where MyTable
corresponds to a MyTable.strings file localized into several languages. When I peek into the .app package, all the localizations are there, sitting inside the "MyBundle.bundle" resource within the app.
以下代码,但是,正确在所有本地化中查找给定字符串的翻译:
The following code, however, correctly finds the translations for a given string in all localizations:
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));
}
所以当捆绑包是实际的 MyBundle.bundle时/<LanguageCode>.lproj
文件夹,字符串查找有效。但显然这违背了iOS提供的自动查找的目的。
So when the bundle is the actual MyBundle.bundle/<LanguageCode>.lproj
folder, the string lookup works. But obviously this defeats the purpose of the automatic lookup provided by iOS.
(注意 [NSBundle myResourcesBundle]
以上只是一个静态便捷方法来获取子项目的自定义包。)
(Note that [NSBundle myResourcesBundle]
above is simply a static convenience method to fetch my custom bundle for the sub-project).
-
编辑:我一直在尝试这个,如果我从子项目的包中删除 en.lproj
文件夹,那么它正确使用设备或模拟器的区域设置。
Edit: I've been experimenting with this some more, and if I delete the en.lproj
folder from my sub-project's bundle, then it correctly uses the locale of the device or simulator.
例如,我有:
MyApp.app/
|
- MyResources.bundle/
|
- en.lproj/
|
- zh-Hans.lproj/
当我将模拟器(或设备)设置为简体中文它在 en.lproj
中查找字符串,即使语言环境是 zh-Hans
。如果我删除 en.lproj
文件夹并重启应用程序,它会正确使用zh-Hans本地化。
When I set the simulator (or device) to Chinese Simplified it looks up strings in en.lproj
even though the locale is zh-Hans
. If I delete the en.lproj
folder and restart the app it correctly uses the zh-Hans localization.
推荐答案
我现在对此有一个hacky解决方案,但如果有人有更好的答案(或解释上述原因不起作用的解释),我将不胜感激。
I now have a hacky solution to this, but would appreciate if someone has a better answer (or explanation for why the above doesn't work).
我扩展了我的NSBundle类别以包含首选语言资源:
I expanded my NSBundle category to include a preferred language resource:
标题
@interface NSBundle (MyBundle)
+ (NSBundle*) myResourcesBundle;
+ (NSBundle*) myPreferredLanguageResourcesBundle;
@end
实施
@implementation NSBundle (MyBundle)
+ (NSBundle*) myResourcesBundle
{
static dispatch_once_t onceToken;
static NSBundle *myLibraryResourcesBundle = nil;
dispatch_once(&onceToken, ^
{
myLibraryResourcesBundle = [NSBundle bundleWithURL:[[NSBundle mainBundle] URLForResource:@"MyResources" withExtension:@"bundle"]];
});
return myLibraryResourcesBundle;
}
+ (NSBundle*) myPreferredLanguageResourcesBundle
{
static dispatch_once_t onceToken;
static NSBundle *myLanguageResourcesBundle = nil;
dispatch_once(&onceToken, ^
{
NSString *language = [[[NSBundle myResourcesBundle] preferredLocalizations] firstObject];
myLanguageResourcesBundle = [NSBundle bundleWithPath:[[NSBundle myResourcesBundle] pathForResource:language ofType:@"lproj"]];
if( myLanguageResourcesBundle == nil )
{
myLanguageResourcesBundle = [NSBundle myResourcesBundle];
}
});
return myLanguageResourcesBundle;
}
@end
然后我有一个简单的宏获取我的本地化字符串:
I then have a simple macro for getting my localized strings:
#define MyLocalizedDocumentation(key, comment, chapter) \
NSLocalizedStringFromTableInBundle((key),(chapter),[NSBundle myPreferredLanguageResourcesBundle],(comment))
这个解决方案只是首选来自 NSLocale
的语言代码,然后检查是否存在该语言的包。如果没有,它会回退到主资源包(也许它应该遍历NSLocale preferredLanguage索引来检查一个包是否存在?有人知道吗?)
This solution simply gets the preferred language code from NSLocale
and then checks to see if a bundle exists for that language. If not, it falls back to the main resource bundle (perhaps it should iterate through the NSLocale preferredLanguage indices to check if a bundle exists? Does anyone know?)
这篇关于iOS App Bundle中的多个本地化.strings文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!