12

Cocoa に組み込まれているローカリゼーション システムで奇妙な問題が発生しています。genstrings を使用してプロジェクト用の localizable.strings ファイルを作成すると、ファイルが読み込まれ、アプリで期待どおりに文字列が置き換えられます。

ただし、他のすべてのビルドでのみ機能するようです。XCode でコードをビルドし、デバイスでテストすると、正しい文字列が問題なく表示されます。ただし、次のビルドでは文字列ファイルのロードに失敗します (少なくとも、それは私が想定していることです)。これはランダムではありませんが、他のすべてのビルドでは予想どおりです。私は、Localizable.strings ファイルに対して特別なことは何もしていません。

この問題の診断をどこから始めればよいかさえわかりません。Cocoa でローカリゼーションを行った経験のある人はいないかと思っていました。

次のように、コードベース全体で NSLocalizedString を使用しています。

NSLocalizedString(@"ReallyNewGame", @"Are you sure you want to start a new game?")

Localizable.strings ファイルの対応するエントリ:

/* Are you sure you want to start a new game? */
"ReallyNewGame" = "Do you really want to start a new game?";

これが私の Info.plist の関連部分です。

<key>CFBundleDevelopmentRegion</key>
<string>English</string>

これは、アプリの他のビルドごとに何が起こるかのスクリーンショットです。

正しい: 正しいときの見え方

正しくない: 間違ったときの見え方

なぜこれが起こるのか、私は困惑しています。Localizable.strings ファイルを手動で使用することはなく、XCode でプロジェクトを数回クリーンアップしました。正しい方向へのポインタは大歓迎です。さらに情報が必要な場合は、提供を試みます。

ありがとう!

4

7 に答える 7

7

明確な回答はできませんが、いくつかの方法を提案することはできます。私は実際に多言語アプリを今持っていないので、これのほとんどは私が読んで集めたものです(私はすぐにそれを持っているかもしれないので、あなたの問題は私にとって興味深いです):

1) Apple は、en.lproj を支持して English.lproj のユーザーを非推奨にしました。いずれにせよ、CFBundleDevelopmentRegion 値として "English" を使用する場合は、フォルダーの名前を "en" ではなく "English" にすることが重要です。

2)文字列ファイルはUTF16である必要があり、ファイルインスペクター(Xcodeの一番右のペイン)にそのように記載されています

3) ローカリゼーション ファイルが Xcode に正しく入力されていることを確認するためのグラフィカルなポインターが含まれている素敵な以前の質問があります (したがって、Xcode はそれを認識し、それらを処理する必要があることを認識しています)。

4) ファイルが破損している可能性があります。リソース ガイドには、「plutil -lint Localizable.strings」を実行して、ファイルが正しいことを確認できると記載されています。

5) 余談ですが、 Mac App Store Appは文字列ファイルをマージする (上書きするのではなく) (追加するたびに) 便利なユーティリティであると多くの人が指摘しています。

6) 問題が解決しない場合は、アプリの初回起動時に AppDelegate "didFinishLaunchingWithOptions" (上部) に以下を追加します。

NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSLog(@"Strings file: %@", [bundel pathForResource:@"Localizable" ofType:@".strings"]);
NSLog(@"Localizations: %@" [bundle localizations]);
NSLog(@"Local Dict: %@", [bundle localizedInfoDictionary]];
NSLog(@"localizedStringForKey: %@", [bundle localizedStringForKey:@"ReallyNewGame"value:@"WTF???" table:nil];
NSLog(@"Localized String: %@", NSLocalizedString(@"ReallyNewGame", @"Are you sure you want to start a new game?"));
exit(0); // just testing the above for now

アプリを数回実行します。出力は同じである必要があります。この回答にコメントを追加しない場合は、さらにドリルダウンできます。それが同じであれば、何かがアプリ内でさらに破損を引き起こしています。

于 2012-07-18T13:54:11.110 に答える
6

それが他の誰かを助ける場合:

私はまったく同じ問題に遭遇しました。他のすべてのビルドでローカリゼーションが機能しませんでした。バンドルの内容を調べたところ、en.lproj の Localizable.strings が破損していることがわかりました。ファイルの長さは 4k であるはずなのに、76 バイトしかありませんでした。次のビルドでは、破損がなくなり、再び元に戻り、その後なくなりました...

別のプロジェクトからフォルダーをコピーしたときに、追加の Localizable.strings フォルダーをプロジェクトにコピーしたことが判明しました。余分な Localizable.strings フォルダーを削除すると、すべてが魔法のように機能しました。うわー!

于 2013-05-01T03:41:42.500 に答える
3

この問題は次の場合に発生します。

  • 少なくとも 2 つのファイルが あります*/<locale>.lproj/<table_name>.strings。たとえば、2 つのファイルがあります。*/en.lproj/Localizable.strings
  • *.stringsファイルで複数の言語をサポートしている

おそらく.strings、同じ名前で 2 つ以上のファイルを作成することはないでしょう。この問題は通常、リソースにファイルがある外部ライブラリを使用する場合に発生します。Localizable.stringsおそらくリソースLocalizable.stringsにファイルがありそれが XCode が解決できない競合です。

TL; DR; 一般的なヒント:他の開発者がサード パーティ コードとして使用するライブラリを作成する場合は、ファイルを作成してその中で使用する代わりに、カスタム名のローカライズ可能な文字列テーブル (例: ) を作成して使用します。Localizable.stringsNSLocalizedString()MyLibName.stringsNSLocalizedStringFromTable

問題の例と詳細な説明:

「problem-demo」リポジトリを作成しました: https://github.com/kajot/LocalizedStringsMergingFailure

特に、他のすべての実行に失敗するテスト: https://github.com/kajot/LocalizedStringsMergingFailure/blob/master/LocalizedStringsMergingFailureTests/LocalizedStringsMergingFailureTests.m

│  ├── KJAppDelegate.h
│   ├── KJAppDelegate.m
│   ├── Localizations1
│   │   ├── de.lproj
│   │   │   └── Localizable.strings
│   │   └── en.lproj
│   │       └── Localizable.strings
│   ├── Localizations2
│   │   ├── de.lproj
│   │   │   └── Localizable.strings
│   │   └── en.lproj
│   │       └── Localizable.strings

OTHERビルドごとに、XCode はLocalizable.stringsバンドル内に破損したファイルを作成します。解決策: 同じ名前の複数のLocalizedStringテーブルを同じターゲットに作成/追加しないでください。

LocalizedStringテーブルは一連の*/<locale>.lproj/<tableName>.stringsファイルです。上記の例では、2 つのテーブルがあり、それぞれに名前が付けられLocalizableています (テーブルのデフォルト名)。

テーブルが呼び出された場合Localizable、次を使用してテーブルからローカライズされた文字列を取得します

`NSLocalizedString(key, optionalComment)`.

解決:

これらの 2 つのテーブルをマージする (対応するファイルを同じ言語からの翻訳で連結する) か、テーブルの 1 つの名前を変更することができます。

2 番目のアプローチの例 (テーブルの 1 つの名前を変更):

│  ├── KJAppDelegate.h
│   ├── KJAppDelegate.m
│   ├── Localizations1
│   │   ├── de.lproj
│   │   │   └── Localizable.strings
│   │   └── en.lproj
│   │       └── Localizable.strings
│   ├── Localizations2
│   │   ├── de.lproj
│   │   │   └── NewTableName.strings
│   │   └── en.lproj
│   │       └── NewTableName.strings

NewTableNameこれで、 を使用して新しいテーブル ( ) から翻訳を取得し、 を使用NSLocalizedStringFromTable(key, @"NewTableName", optionalComment) して「元の」テーブル ( Localizable)から翻訳を取得できますNSLocalizedString(key, optionalComment)

于 2014-08-13T22:12:05.480 に答える
0

アプリアイコンに関して同様の問題がありました。アプリにはいくつかのターゲットがあり、すべてが異なるアプリ アイコンを持っていました。何らかの理由でアプリ アイコンの 1 つが破損していたため、すべてのターゲットが他のターゲットのアプリ アイコンに切り替わりました。1 つのターゲットが他のターゲットの app-icon を認識できないため、xcode で両方のターゲットに使用されず、両方のターゲットにマークされている場合、これはかなり奇妙です。

破損したpngを削除し、プロジェクトに新たに追加することで、この問題を解決しました。i18n ファイルでこれを行うと、それも役立つかもしれません。ただし、xcode からの参照だけでなく、ファイル全体を削除するようにしてください。textwrangler などの外部エディターでファイルを開き、テキストを新しいファイルにコピーしてから、代わりにこれを使用することをお勧めします。

幸運を。

于 2012-07-18T15:47:47.173 に答える
0

他のスレッドが役立つ可能性があります... 1 つの iOS アプリ内の複数の Localizable.strings ファイル

繰り返しますが、おそらくクリーンアップしてから、xcode からアプリをビルドできます...

于 2012-07-14T06:03:24.807 に答える
0

あなたが経験した行動は、まったく正常です。なぜ?


これらの行を確認すると、元のマクロ定義の関連部分NSLocalizedString:

#define NSLocalizedString(key, comment) \
        [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]

commentパラメータが不正なパラメータであることがわかります。使用されることはありません。(コードを読む開発者向けです)


さらに、クラスリファレンスを確認すると、メソッドNSBundleの戻り値について次の興味深いことがわかります。-localizedStringForKey:value:table:

戻り値

value が nil または空の文字列で、ローカライズされた文字列がテーブルに見つからない場合は、keyを返します。

ファイルにこのキーの値がない可能性があるため、これがキーを取り戻す理由です。Localizable.string

悲しいニュースですが、それは正常です。


解決策は次のとおりです。

NSLocalizedString(@"Are you sure you want to start a new game?", @"");

そしてあなたのLocalizable.stringファイルで:

@"Are you sure you want to start a new game?" = "Do you really want to start a new game?";
于 2012-07-18T16:06:25.760 に答える
0

私はちょうど私を殺していた何かを見つけた !私は同じ問題を抱えていました:STRINGSファイルによっては、うまくいくこともあれば、うまくいかないこともあります/

私が見つけたのは、.strings ファイルの一部の行が二重のセミコロンで終わっている場合です。

;;

以下のすべての行は無視されます!

例えば: これはうまく機能します: ご覧のとおり、NSLocalizationString コマンドはテンプレートの文字列を正しく置き換えます

ここで、セミコロンが 2 つあることに注意してください

上の画像はうまく機能します: ご覧のとおり、NSLocalizationString コマンドはテンプレートの文字列を正しく置き換えます。それは完全な混乱です!リソースのコンパイル エラーはありません。ただの悪夢!

誰かが不眠症にならないように助けてくれることを願っています!

于 2019-12-16T21:28:11.493 に答える