2017-05-18 12 views
2

私は現在、特定の政府ガイドライン(医療とウェルネスの言葉遣い)のために、アプリケーションの言語を変更する必要があるクライアントを支援しています。彼らのアプリは巨大で、すべての文字列はコードに含まれています。つまり、(stringWithFormat/hardcoded)、外部テーブルにはありません。これは大きな手作業になります。NSStringサブクラスまたはラッパークラスまたはカテゴリ

未定義の時点で、クライアントは、現在の言葉に戻るという承認を受け、文字列を元に戻したいと考えています。変更のほとんどは、文字通り問題の少ない単語に1つの問題のある単語を切り替えることになります。

私は、実行時にboolスイッチに基づいて文字列を変更することができれば、手作業を排除し、必要に応じて言語を切り替えることができると考えました。

初の試み:

+ (instancetype)stringWithFormat:(NSString *)format, ... 
{ 
    va_list args; 
    va_start(args,format); 
    //todo check flag if we're changing the language 
    //todo replace problematic word from 'format' 
    NSString *result = [NSString stringWithFormat:format,args]; 

    return result; 
} 

私が最初にすぐに問題のある単語を置き換えるためにstringWithFormatをオーバーライドするカテゴリをコード化されました。私はstringWithFormatの元の実装を失うことを忘れていました。これは無限の再帰をもたらしました。

次の試行(サブクラス):

私はNSStringのをサブクラス化する試みを始めたが、私のソリューションは、クラスクラスタをサブクラス化した場合、クラスクラスタをサブクラス化するので、私は私の問題を理解していなかったことを言ってStackOverflowのポストを直撃ほとんど行われていません。

最後のオプション(ラッパー):

私の最後の試みは、ラッパークラスが、敗北手動でアプリ内の各文字列を模索することを避けるためにした本来の目的のようなものを書くことであろう。

私はもうこの問題にどのように近づくべきかわかりません。コアクラスの1つに機能を追加/オーバーライドする必要がある場合はどうすればよいですか。

+1

関連:[NSArrayのか、他のクラスクラスタモンキーパッチする方法はありますかスウィズル?]この解決策は、しかし、働いていたほとんどの部分について(http://stackoverflow.com/q/11751473) –

答えて

1

もっとシンプルな解決策があります。

displayString *NSString = NSLocalizedString(@"displayString", nil); 
cancelButtonTitle *NSString = NSLocalizedString(@"cancelButtonTitle", nil); 

は、その後、あなたのアプリ内のLocalizable.stringsファイルを作成し、表示されるべき実際の値を定義します:代わりに、実際の文字列のキーを使用して、 NSLocalizedString使用
"displayString" = "The string to display in English" 
"cancelButtonTitle" = "Cancel" 

あなたがローカライズを置きます。文字列ファイルをアプリケーションのバンドルに入れ、アプリケーションはそれを使用して実行時に文字列の置換を行います。

言語ごとに異なるバージョンのLocalizable.stringsを定義することもできます。たとえば、ユーザーが言語をスペイン語に設定した場合は、NSLocalizedString()を呼び出すとスペイン語版が表示されます。

(前述のように、NSStringはクラスクラスタです。つまり、さまざまなプライベートサブクラスのパブリックインターフェイスです。NSStringの作成時に取得するプライベートサブクラスは、

1

ハードコーディングされた文字列の場合は、他の方法はありませんが、何らかの並べ替えの文字列コンバータクラスに割り当てることによってそれらを手動で変更することはできません。だから、それらのため:

yourmom.text = @"Hi Mom"; 
yourdad.text = [NSString stringWithFormat:@"%@ and Dad!",yourmom.text]; 

あなたは絵コンテやxibs内の文字列については、あなたがのviewDidLoadでの反復ループによってそれらを変更することができ

yourmom.text = [StringConverter string:@"Hi Mom"]; 
yourdad.text = [StringConverter string:@"%@ and Dad!" placeHolder:yourmom.text]; 

のようなものに割り当て、これらの種類を変更する必要があります。がんばろう。

1

あなたの最初の試みのアイデアには何も問題はありませんが、その実装に少し間違いがあります。変更:

NSString *result = [NSString stringWithFormat:format,args]; 

へ:

NSString *result = [NSString alloc] initWithFormat:format arguments:args]; 

stringWithFormat:の拡大で、傍受が動作します。

この特定の状況でクラスクラスターについての考え方は赤い鳴き声ですが、クラスターのフロントクラス(NSString)はクラスメソッド(+stringWithFormat:)の実装を提供する必要があるため、単純なカテゴリーを使用してそれらを傍受できます。

しかし+stringWithFormat:ように注意してください傍受ました。私の最初の簡単なテストは単に "d"を "c"に変更して "ウィンドウ"を "ウィンコウ"に変更したのと同じように、単純なテストではフレームワークによって多く使われていて、プロパティ "ウィンドウ"をバインドするXcodeのデフォルトアプリケーションのバインディング設定が破られました...

健康関連の単語を変更していると、文字列全体が改善されます。

より良い方法は、コード内のすべてのリテラル文字列に一致するようにREを書き込んで、変換を行うために書き込む関数(メソッドではない)の代わりにfunction(string)に置き換えることです。

HTH

+0

私はぶつかる。 **キャッチされていない例外 'NSInvalidArgumentException'のためアプリを終了します。理由: 'appendStringを使用して不変オブジェクトを変更しようとしました:' これらの変更を加えました。 crashlytics/fabricとは何か。だからあなたは正しい...それはいくつかのフレームワークを壊す。 :D – Atomhax

+0

このstringWithFormatはNSMutableStringでも使用されていますが、このオーバーライドされた関数からNSStringを返すだけですか?だから、私はMutable Stringsを考慮に入れて実装を変更する必要があります。 – Atomhax

+1

NSMutableStringにカテゴリを追加しようとしましたか?フレームワークを破壊することに対する懸念は、それ自体の傍受ではなく、メソッドの*動作*をどのように変更するかです。私は方法を置き換えることが最善のアプローチだとは言いませんが、あなたが求めているようなソースの変更を最小限に抑えるという利点があります。 – CRD

関連する問題