【问题标题】:Static library and internationalization静态库和国际化
【发布时间】:2012-09-18 12:15:40
【问题描述】:

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

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];
}

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

【问题讨论】:

    标签: xcode internationalization static-libraries


    【解决方案1】:

    我在做同样的事情时遇到了同样的问题:我有一个静态库和一个包含图像、本地化字符串等的配套捆绑文件。

    我发现静态似乎无法找出正确的设备本地化(很抱歉,我无法找到此问题的原因),我已通过以下方式修复:

    @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];
    }
    

    【讨论】:

    • 不客气,Niko,如果您能找到问题的原因,请告诉我。
    • 确实,不过没问题,我只有几张图片。
    • @Niko 有谁明白为什么它不能正常工作?
    • 嗨,Anastasia,不是真的。我没有尝试对这个问题进行更多调查,因为它是这样工作的:)
    • 您如何处理捆绑中的可本地化字符串? Xcode 似乎不允许我将可本地化的字符串拖到 .bundle 文件夹中...
    【解决方案2】:

    我不得不修改 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。

    【讨论】:

      猜你喜欢
      • 2015-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多