bekkou68 の日記

Gogengo! や IT 技術など。

Localizable.strings で選ばれるデフォルトの言語を設定する

やりたいこと

20カ国に公開するアプリをつくっていて、まずは日本語と英語だけの Localizable.strings を用意しているとします。
そのアプリを言語設定を母国語にしているアーロンさんが使うとします。彼の母国語は日本語・英語以外ではない言語です。彼がアプリを起動したら選択される .stringsファイルを英語ものにしたい。というお話しです。

結論

コードでやることにしました。xx には適宜プロジェクトのプリフィックスを書いてください。

NSBundle+xx_localizedString.h
#import <Foundation/Foundation.h>

@interface NSBundle (xx_localizedString)

- (NSString *)xx_localizedString:(NSString *)key;

@end
NSBundle+xx_localizedString.m
#import "NSBundle+xx_localizedString.h"

@implementation NSBundle (xx_localizedString)

// 用意した .strings 以外の言語設定だったらデフォルトを英語にする
- (NSString *)xx_localizedString:(NSString *)key
{
    NSString *localizedString = nil;
    
    NSString *preferredLanguage = [[NSLocale preferredLanguages] objectAtIndex:0];
    if ([preferredLanguage isEqualToString:@"en"] || [preferredLanguage isEqualToString:@"ja"]) {
        localizedString = NSLocalizedString(key, nil);
    } else {
        NSString *path = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"];
        NSBundle *languageBundle = [NSBundle bundleWithPath:path];
        localizedString = [languageBundle localizedStringForKey:key value:@"" table:nil];
    }
    
    return localizedString;
}

@end
xx.pch
#define XXLocalizedString(key) [[NSBundle mainBundle] xx_localizedString:key]
使い方
XXLocalizedString(@"something");
参考

こちらの記事の実装を参考にしました。また、iRate似たような趣旨のコードがあります。

他の方法はないものか

Base Internationalization で Localizable.string にも設定できるのではないかと思ったのですが、うまくいかなかったです。これって Storyboard に対してだけの機能なのでしょうか。

考察

不都合が起きるとすれば、アーロンさんが意図して「母国語>日本語>英語」の優先度で言語設定をしていた場合に起きそうです。つまり、母国語のローカライズが対応していなければ次に見たい言語は日本語である場合です。今回の対応をすると、日本語を期待しているアーロンさんの端末で英語が表示されてしまいます。
今回の仕様は、日本語・英語以外を母国語とする人たちがアプリをつかう場合、英語のほうが読める人が多いのでそのほうがいいのではないかという仮定のもととなっています。

言語設定の仕組みと NSLocalizedString の挙動

前述した「母国語>日本語>英語」の順序に言語設定するにはどうすればいいのでしょうか。Mac OS だと自分で順序を変えられますiOS では設定画面で選んだ言語の最新降順となります。たとえば、「英語, 日本語, 母国語」の順序で設定すると「母国語, 日本語, 英語」の順序となります。スタックされるイメージです。

優先度がつけられた言語設定は NSLOG(@"%@", [NSLocale preferredLanguages]); とすると確認できます。

(
    ar,
    ja,
    en,
    it,
    ... (snip) ...

ローカライズの仕組みですが、NSLocalizedString を実行すると preferredLanguages の頭から探していき、最初にマッチした言語をローカライズする。というロジックのようです。この挙動はあくまで実機で確認しただけです。同じことを書いている文献はいくつか見つけられましたが、明記されている公式のドキュメントが見当たらなかったので見つけたいです・・。

おわりに

間違いがあったり、よりよい方法がありましたら教えてください。