デバイスのユーザー設定を無視して、アプリのUIからアプリの言語を設定したいとします。これは珍しいことですが、ここに行きます...
まず、すべての言語文字列を次のようなディレクトリ構造に書き込みます。
i18n/en.lproj/Localizable.strings
i18n/ar.lproj/Localizable.strings
サポートされている追加の言語ごとに、対応する2文字のコードを使用して追加のディレクトリを作成します。
ファイルがi18nリソースとして認識される場合、次のように表示されます。

ファイルには、次の形式のkey=valueがあります。
"button.back" = "ظهر";
コードで、ローカライズ可能な文字列をキーに置き換えます。例:
[self.stateBtn setTitle:localize(@"button.back") forState:UIControlStateNormal];
通常は使用しますNSLocalizedString(@"key",@"fallback")
が、iPhoneの設定を無視したいのでlocalize(@"key")
、次の実装を持つ上記のマクロを作成しました。
Localization.h
#ifndef localize
#define localize(key) [[Localization sharedInstance] localizedStringForKey:key]
#endif
@interface Localization : NSObject
@property (nonatomic, retain) NSBundle* fallbackBundle;
@property (nonatomic, retain) NSBundle* preferredBundle;
@property (nonatomic, copy) NSString* fallbackLanguage;
@property (nonatomic, copy) NSString* preferredLanguage;
-(NSString*) localizedStringForKey:(NSString*)key;
-(NSString*) pathForFilename:(NSString*)filename type:(NSString*)type;
+(Localization*)sharedInstance;
@end
Localization.m
#import "Localization.h"
@implementation Localization
+(Localization *)sharedInstance
{
static dispatch_once_t pred;
static Localization *shared = nil;
dispatch_once(&pred, ^{
shared = [[Localization alloc] init];
[shared setPreferred:@"en" fallback:@"ar"];
});
return shared;
}
-(void) setPreferred:(NSString*)preferred fallback:(NSString*)fallback
{
self.fallbackLanguage = fallback;
self.preferredLanguage = preferred;
NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"Localizable" ofType:@"strings" inDirectory:nil forLocalization:self.fallbackLanguage];
self.fallbackBundle = [[NSBundle alloc] initWithPath:[bundlePath stringByDeletingLastPathComponent]];
bundlePath = [[NSBundle mainBundle] pathForResource:@"Localizable" ofType:@"strings" inDirectory:nil forLocalization:self.preferredLanguage];
self.preferredBundle = [[NSBundle alloc] initWithPath:[bundlePath stringByDeletingLastPathComponent]];
}
-(NSString*) pathForFilename:(NSString*)filename type:(NSString*)type
{
NSString *path = [self.preferredBundle pathForResource:filename ofType:type inDirectory:nil forLocalization:self.preferredLanguage];
if (!path) path = [self.fallbackBundle pathForResource:filename ofType:type inDirectory:nil forLocalization:self.fallbackLanguage];
if (!path) NSLog(@"Missing file: %@.%@", filename, type);
return path;
}
-(NSString*) localizedStringForKey:(NSString*)key
{
NSString* result = nil;
if (_preferredBundle!=nil) {
result = [_preferredBundle localizedStringForKey:key value:nil table:nil];
}
if (result == nil) {
result = [_fallbackBundle localizedStringForKey:key value:nil table:nil];
}
if (result == nil) {
result = key;
}
return result;
}
@end
これは、アラビア語ファイル内のキー文字列のルックアップを使用し、キーが欠落している場合は、アラビア語ファイル内をルックアップします。逆の場合は、ボタンハンドラーから次の手順を実行します。
[[Localization sharedInstance] setPreferred:@"ar" fallback:@"en"];
Githubのサンプルプロジェクト。
ローカリゼーションが機能しない場合
ローカリゼーションが機能しない場合は、plutilコマンドラインツールを使用してファイルの形式を確認してください。次のように出力されますLocalizable.strings: OK
。例:
$ plutil -lint Localizable.strings
Localizable.strings: OK
この形式については、「国際化プログラミングトピック」> 「文字列リソースのローカライズ」で説明されています。オプションで、コメントを追加// single-line
または/* multi-line */
コメントできます。ラテン語以外の言語の場合は、Localized.stringsをUTF-16でエンコードすることをお勧めします。XCodeのインスペクターペインでエンコーディング間で変換できます。
それでも機能しない場合は、ターゲットのファイルのコピーフェーズでLocalizable.stringsファイルをコピーしていることを確認してください。Localizable.stringsファイルをそこに追加すると、赤で表示されることがあります。ファイルが黒で表示されるまでそれを続けてから、赤のファイルを削除してください(Xcodeのせいです)。
