3

静的ライブラリについて質問があります。ライブラリ内のテキストをローカライズする必要があります。そこで、さまざまなローカライズされたファイルを配置するバンドルを作成しました。次に、次のような関数を作成しました。

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

しかし、私がそれを使用すると、常に英語にローカライズされた文字列が返されます (私の電話言語はフランス語です)。何故かはわからない。

4

2 に答える 2

3

I've got the very same issue when doing the exactly same: I've a static library and a companion bundle file with image, localized string, etc..

I've figured out that seems that the static can't figure out the correct device localization (I'm sorry but I wasn't able to find the reason of this issue) and I've fixed by doing this:

@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

As you can see I have created a category of NSBundle with a Class method that act very similar to [NSBundle mainBundle] and that return me the correct bundle for the static libray so I can use it everywhere I want, for example:

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

The code is very simple first I find the path for the static library bundle, find the current device language and then I create a new NSBundle whose path is 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];
}
于 2012-09-18T12:40:56.837 に答える
1

ルカの答えを変更して、思い通りに機能させる必要がありました。私の問題は非常に似ていました。使用するアプリケーションからバンドルされたローカライズされた文字列を使用しても、正しい [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 を見つけます。

于 2014-04-21T18:53:26.843 に答える