カスタム定義の「ローカリゼーション」で NSLocalizedString インフラストラクチャ (localizable.strings に基づく) を使用することは可能ですか?
実は、男性と女性の言い回しが異なる言語がいくつかあります。最初の起動時にユーザーの性別を尋ねてから、適切なフレーズを使用したいと考えています。もちろん、どちらも同じ言語に基づいています。私は自分のコードでそれを行うことができますが、可能であれば簡単な方法で行いたいと思います.
カスタム定義の「ローカリゼーション」で NSLocalizedString インフラストラクチャ (localizable.strings に基づく) を使用することは可能ですか?
実は、男性と女性の言い回しが異なる言語がいくつかあります。最初の起動時にユーザーの性別を尋ねてから、適切なフレーズを使用したいと考えています。もちろん、どちらも同じ言語に基づいています。私は自分のコードでそれを行うことができますが、可能であれば簡単な方法で行いたいと思います.
コメントをデフォルト値として使用する NSLocalizedString を使用するカスタム実装を次に示します。
(NSLocalizedStringWithDefaultValue は genstring では正しく動作しないため、この解決策を提案しました)
1. コンパイル済みヘッダー (.pch ファイル) で、「NSLocalizedString」マクロを再定義します。
// cutom NSLocalizedString that use macro comment as default value
#import "LocalizationHandlerUtil.h"
#undef NSLocalizedString
#define NSLocalizedString(key,_comment) [[LocalizationHandlerUtil singleton] localizedString:key comment:_comment]
2. ローカリゼーション ハンドラを実装するクラスを作成する
#import "LocalizationHandlerUtil.h"
@implementation LocalizationHandlerUtil
static LocalizationHandlerUtil * singleton = nil;
+ (LocalizationHandlerUtil *)singleton
{
return singleton;
}
__attribute__((constructor))
static void staticInit_singleton()
{
singleton = [[LocalizationHandlerUtil alloc] init];
}
- (NSString *)localizedString:(NSString *)key comment:(NSString *)comment
{
// default localized string loading
NSString * localizedString = [[NSBundle mainBundle] localizedStringForKey:key value:key table:nil];
// if (value == key) and comment is not nil -> returns comment
if([localizedString isEqualToString:key] && comment !=nil)
return comment;
return localizedString;
}
@end
3. 使ってみよう!
Localized.strings ファイルがビルドごとに更新されるように、アプリのビルド フェーズに実行スクリプトを追加してください。つまり、新しいローカライズされた文字列が Localized.strings ファイルに追加されます。
私のビルド フェーズ スクリプトはシェル スクリプトです。
Shell: /bin/sh
Shell script content: find . -name \*.m | xargs genstrings -o MyProjectFolder
したがって、コードに次の新しい行を追加すると、次のようになります。
self.title = NSLocalizedString(@"view_settings_title", @"Settings");
次にビルドを実行すると、./Localizable.scripts ファイルに次の新しい行が含まれます。
/* Settings */
"view_settings_title" = "view_settings_title";
また、「view_settings_title」のキー == 値であるため、カスタム LocalizedStringHandler はコメント、つまり「Settings」を返します。
ほら:-)
NSLocalizedString は、NSBundle.h で定義された単なるマクロ
です。必要に応じて、NSGenderAwareLocalizedString などを再定義するか、新しいものを作成します。
新しいマクロを使用すると、好きなことを自由に行うことができます。言語ごとに 2 つの文字列ファイル (1 つは男性用、もう 1 つは女性用) です。または、男性のローカライズされた文字列のキーから女性のローカライズされた文字列のキーを導出する規則を定義できます。
これには特別なメカニズムがあります。Apple リファレンスから: Searching for Custom Functions With genstrings
ツールは、
genstrings
デフォルトで Core Foundation および Foundation 文字列マクロを検索します。これらのマクロの情報を使用して、プロジェクトの文字列ファイルに文字列エントリを作成します。コード内でカスタムの文字列読み込み関数を探し、標準マクロに加えてそれらの関数を使用するように genstring に指示することもできます。カスタム関数を使用して組み込みの文字列読み込みルーチンをラップし、追加の処理を実行するか、デフォルトの文字列処理動作を独自のカスタム モデルに置き換えることができます。独自のカスタム関数で genstring を使用する場合、関数は、Foundation マクロで使用される命名規則とフォーマット規則を使用する必要があります。関数のパラメーターは、対応するマクロのパラメーターと正確に一致する必要があります。を呼び出すときは
genstrings
、オプションを指定し、-s
その後に NSLocalizedString マクロに対応する関数の名前を指定します。他の関数名は、このベース名から作成する必要があります。たとえば、関数名を指定した場合MyStringFunction
、他の関数名は 、、および である必要がMyStringFunctionFromTable
ありMyStringFunctionFromTableInBundle
ますMyStringFunctionWithDefaultValue
。genstrings
ツールはこれらの関数を探し、それらを使用して対応する文字列ファイルを作成します。
独自の動作を実装するには、NSBundle
メソッドを使用しますlocalizedStringForKey:value:table:
コメントをデフォルト値として使用する NSLocalizedString を使用するカスタム実装を次に示します。
--> ここでは 2 つの言語 (英語とイタリア語) に変換します。
--> このメソッドを appdelegate クラスに入れます
- (NSString*)languageSelectedStringForKey:(NSString*) key {
NSString *path = nil;
NSString *language = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppLanguage"];
if ([language isEqualToString:@"English"])
path = [[NSBundle mainBundle] pathForResource:@"en" ofType:@"lproj"];
else if ([language isEqualToString:@"Italian"])
path = [[NSBundle mainBundle] pathForResource:@"it" ofType:@"lproj"];
NSBundle* languageBundle = [NSBundle bundleWithPath:path];
NSString* str=[languageBundle localizedStringForKey:key value:@"" table:nil];
return str;
}
--> このメソッドを呼び出す
self.title = [appDelgate languageSelectedStringForKey:@"Back"];
選択した言語に変換します。
@Guillaume は、実際に実装を示すことなく、最適なソリューションを提供します。質問の作者はそれを理解できなかったので、将来の人々のためにそれを含めることにしました. スレッドは役に立ちましたが、今では役に立ちました。:)
@Guillaume が述べたように、最善の解決策は、テーブルのルックアップを使用してカスタム マクロを作成することです。「テーブル」は、バリアントを含む他のファイルの名前です。この場合、ファイル名を 'Female.strings' と仮定します。
これにより、最大限の柔軟性が確保され、両方のケースのエントリを定義する必要のないソリューションが得られます。すべてのフレーズが女性形であるとは限らないため、これは実際にあなたの場合に非常に役立ちます.
その結果、次のソリューションでは重複するエントリは必要ありません。これは非常に優れています。
最初にマクロを定義します。
#define SXLocalizedString(key, comment) [Utility SXLocalizedString:key with:comment]
次に、展開された関数を次のように定義します。
+ (NSString*)SXLocalizedString:(NSString*)str with:(NSString*)comment {
NSString* feminine = NSLocalizedStringFromTable(str, @"Female", comment);
NSString* value = NSLocalizedString(str, comment);
if ([self userIsFemale] &&
feminine) {
// choose the feminine version of the string
value = feminine;
}
return value;
}