静态库和国际化

时间:2012-09-18 12:15:40

标签: xcode internationalization static-libraries

我对静态库有疑问。我需要在我的库中本地化一些文本。所以我创建了一个包,我在其中放置了不同的本地化文件。然后,我创建了一个这样的函数:

NSString *MyLocalizedString(NSString* key, NSString* comment)
{
    static NSBundle* bundle = nil;
    if (!bundle)
    {
        NSString* path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"MyStaticLib.bundle"];
        bundle = [[NSBundle bundleWithPath:path] retain];
    }

    return [bundle localizedStringForKey:key value:@"" table:nil];
}

但是当我使用它时,它总是返回英文本地化字符串(除了我的手机语言是法语)。我不知道为什么。

2 个答案:

答案 0 :(得分:3)

在执行完全相同的操作时我遇到了同样的问题:我有一个静态库和一个包含图像,本地化字符串等的伴随包文件。

我已经发现似乎静态无法找出正确的设备本地化(对不起但是我无法找到这个问题的原因)并且我已经修复了这样做:

@implementation NSBundle (KiosKitAdditions)

+ (NSBundle *)kioskitBundle
{
    static NSBundle* kioskitBundle = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{

        NSString *libraryBundlePath = [[NSBundle mainBundle] pathForResource:KKBundleName
                                                                      ofType:@"bundle"];

        NSBundle *libraryBundle = [[NSBundle bundleWithPath:libraryBundlePath] retain];
        NSString *langID        = [[NSLocale preferredLanguages] objectAtIndex:0];
        NSString *path          = [libraryBundle pathForResource:langID ofType:@"lproj"];
        kioskitBundle           = [[NSBundle bundleWithPath:path] retain];
    });
    return kioskitBundle;
}

@end

正如你所看到的,我创建了一个NSBundle类,其中一个Class方法与[NSBundle mainBundle]非常相似,并且为静态库提供了正确的包,所以我可以在任何我想要的地方使用它,例如:

#define KKLocalizedString(key) NSLocalizedStringFromTableInBundle(key, @"Localizable", [NSBundle kioskitBundle], @"")

代码非常简单首先我找到静态库包的路径,找到当前的设备语言然后创建一个新的NSBundle,其路径是library_path / device_language.lproj。

这种方法的一个缺点是你需要总是本地化你的所有资产,如果你的包中有很多图像,这可能会很痛苦(但我认为这不太可能)。

如果您不想采用我的类别方法,您可以更改代码:

NSString *MyLocalizedString(NSString* key, NSString* comment)
{
    static NSBundle* bundle = nil;
    if (!bundle)
    {
        NSString *libraryBundlePath = [[NSBundle mainBundle] pathForResource:@"MyStaticLib"
                                                                      ofType:@"bundle"];

        NSBundle *libraryBundle = [NSBundle bundleWithPath:libraryBundlePath];
        NSString *langID        = [[NSLocale preferredLanguages] objectAtIndex:0];
        NSString *path          = [libraryBundle pathForResource:langID ofType:@"lproj"];
        bundle                  = [[NSBundle bundleWithPath:path] retain];

    }

    return [bundle localizedStringForKey:key value:@"" table:nil];
}

答案 1 :(得分:1)

我不得不修改Luca的答案,让它按照我想要的方式工作。我的问题非常相似:使用我的消费应用程序中的捆绑本地化字符串并没有解决纠正[lang] .lproj文件夹的问题。在我的情况下,我有一个我想查找的es.lproj文件夹。但是,如果用户将其首选语言设置为es-MX,则使用[NSLocale preferredLanguages] objectAtIndex:0]将尝试查找不存在的es-MS.lproj文件夹。

@implementation NSBundle (CCPAdditions)

+ (NSBundle *)CCPBundle
{
    static NSBundle* corePaymentBundle = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{

        NSString *libraryBundlePath = [[NSBundle mainBundle] pathForResource:@"ClipCorePayments"
                                                                      ofType:@"bundle"];

        NSBundle *libraryBundle = [NSBundle bundleWithPath:libraryBundlePath];

        for (NSString *langID in [NSLocale preferredLanguages])
        {
            NSString *path = [libraryBundle pathForResource:langID ofType:@"lproj"];
            if (path)
            {
                corePaymentBundle           = [NSBundle bundleWithPath:path];
                break;
            }
        }
    });

    return corePaymentBundle;
}

@end

这将遍历首选语言列表,并检查该路径是否存在。如果缺少es-MX.lproj,它将接下来检查es.lproj等,如果没有其他内容,最终会找到en.lproj。