25

iOSアプリをローカライズしていますが、シミュレーターでは、選択した言語で毎回正しく実行されます。

私のiPhone5でテストすると、アプリが最初に実行されたときにのみ言語が正しく検出されます。デバイスでアプリを再コンパイルして実行するたびに、スペイン語( "es")を選択してテストしているにもかかわらず、言語として"en"が検出されます。

私は以下を使用して言語を検出します:

[[[NSBundle mainBundle] preferredLocalizations] objectAtIndex:0]

私も使用しました:

[[NSLocale preferredLanguages] objectAtIndex:0]

同じ結果。

最初の実行後にアプリを強制終了し、デバイスで再起動すると、言語が正しく検出され続けます。

しかし、アプリを強制終了し、最初の実行後にXcodeを介して再コンパイル/再起動すると、代わりに「en」(英語)が検出されてロードされます。

その後、アプリを完全に削除して、Xcodeを介してアプリを再コンパイル/再インストール/実行しない限り、アプリを強制終了して再起動すると、英語として継続的に検出されます。その後、このサイクルが繰り返されます...最初にデバイスからアプリを削除せずに、その後の再構築/再起動を行うと、誤検出が発生します。

デバイス上の他のすべてのアプリは、常にスペイン語で表示されます。UI全体がスペイン語で表示されます。

更新: iOS 6を実行しているiPad(第3世代)でテストしましたが、同じ動作が発生しています。

更新2:

didFinishLaunchingWithOptionsには、言語を検出するための次のコードがあります:(言語はNSString *です):

language = [[NSLocale preferredLanguages] objectAtIndex:0];

このデバッグステートメントの後に、取得している値と、デバッグのためだけにそれを検出するわずかに異なる方法を比較します。

NSLog(@"Detected language: %@ / %@", language, [[[NSBundle mainBundle] preferredLocalizations] objectAtIndex:0]);

アプリがスペイン語モードで正常に動作する場合、出力は「検出された言語:es / es」と表示され、動作しない場合は「検出された言語:en/en」と表示されます。なぜそれが時々英語としてロードすることを決定するのかまだわかりません...

更新4:皆さんの回答に感謝し、さまざまな提案を試しました。残念ながら、どの提案も問題を解決していないようだったため、 +100の報奨金を授与することができませんでした。誰かが私に役立つ解決策を最終的に見つけた場合、その時点でさらに+50の報奨金を授与します。

更新5: Xcode 4.5から4.5.2に更新しましたが、これと同じ問題が発生しています。

更新6:新しいテストプロジェクトを最初から作成しましたが、完全に正常に機能します。明らかに、私のプロジェクトのレイアウト方法、またはおそらくデータファイルの1つに何か問題があるはずです。次の旅は、プロジェクトを最初から作り直して、ファイルデータを1つずつコピーすることだと思います...

更新7(数か月後):残念ながら、プロジェクトを丹念に再作成することで一時的に(一見)問題を解決した後、この問題に再び直面しています。最初のロードでは言語は正しくレンダリングされますが、その後のロードでは英語に戻ります。

解決済み以下の私の最終的な解決策を参照してください。みんな助けてくれてありがとう。とにかく無駄になるので、私は賞金の一部を使い果たすかもしれません。

4

5 に答える 5

8

私は何ヶ月も後にこの問題を最終的に解決しました!助けてくれたすべての人に感謝します(私はまた、開発チャネルを介してApple開発者と行ったり来たりしました)。

TL; DR:アプリのiCloud Key Valueストア(MKiCloudSync経由)を使用して、デバイス間で(他の多くの予期しないことの中でも)言語設定を誤って同期していました!読む...

私はMKiCloudSyncと呼ばれるサードパーティのクラスを使用しています。これは[NSUserDefaults standardUserDefaults]、アプリのiCloud KeyValueStoreとの同期に役立ちます。私がそれを使い始めたときの私の意図は、バックグラウンドで同期しているいくつかのユーザーのお気に入りを処理できるようにすることでした。

しかし、どのように機能するのか理解していませんでしたが、私が気付いていなかったのは、自分のカスタムアプリ設定以外にもstandardUserDefaults多くのことが書き込まれていることです。standardUserDefaults

だから何が起こっていたのはこれでした:

  1. 初めてアプリを起動します。新しくstandardUserDefaults、言語設定の順序付きリストを格納する内部の「AppleLanguages」キーは、現在のデバイスの選択に基づいて正しいものです。

  2. アプリは指定された言語で正しく表示されます。

  3. バックグラウンドで、MKiCloudSyncはALLstandardUserDefaultsをiCloudに同期します。逆に、このアプリを他の場所で実行した場合、たとえば英語のセットデバイスを使用した場合、そのデバイスは言語設定もiCloudに同期します。そのため、現在実行中のこのアプリでは、実際には言語設定が上書きされています。

  4. ブーム...次にアプリを実行するときは、デバイスで何を選択したかに関係なく、デフォルトの言語として使用されるのはiCloudからプルダウンされたものです。

次のアプリのアップデートで問題を解決するために私が行う予定のこと:

  1. ホワイトリストに登録されたキー名のみを同期できるMKiCloudSyncのフォークバージョンを使用します。

  2. 1回限りのクリーンアップを実行するコードを追加します。最初にアプリのiCloudキーストアをクリーンアップし、次に(このSOの回答に基づいて)このコードを呼び出してユーザーのデフォルトをリセットします。

    NSString * appDomain = [[NSBundle mainBundle] bundleIdentifier]; [[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];

これまでの私のテストでは、この種の問題は解決しました...残念ながら、ユーザーは言語修正を開始するためにアプリを再起動する必要があります。ただし、ほとんどのユーザーはこの問題を経験していないと思います。デフォルトの言語が異なる複数のデバイスを使用する。

于 2012-12-28T19:48:16.417 に答える
3

[設定]->[一般]->[国際]では、場所の言語などを設定するオプションがあります。これをテストしようとしている言語に設定すると、コードが正しい場合に機能します。

于 2012-12-06T08:44:58.563 に答える
2

iPhone5で問題なく手順をテストしました。これにより、ここで何か他のことが起こっていると思います。おそらく、ロケール値の読み取り方法を妨げる何かがあります。

この問題のデバッグを支援するために実行することをお勧めする手順は次のとおりです。

  1. 優先言語の値を取得するメソッドの完全なコードを投稿してください。アプリを実行するたびにメソッドが実行されることを確認してください。
  2. 投稿するコードに、言語設定のテストに使用しているNSLogディレクティブの場所が含まれていることを確認してください。
  3. 最初の実行後、優先言語を別の場所に保存していますか?
于 2012-11-29T21:45:04.060 に答える
2

次のコードで試してください。

LocalizationSystem.h ===

#import <Foundation/Foundation.h>

#define AMLocalizedString(key, comment) \
[[LocalizationSystem sharedLocalSystem] localizedStringForKey:(key) value:(comment)]

#define LocalizationSetLanguage(language) \
[[LocalizationSystem sharedLocalSystem] setLanguage:(language)]

#define LocalizationGetLanguage \
[[LocalizationSystem sharedLocalSystem] getLanguage]

#define LocalizationReset \
[[LocalizationSystem sharedLocalSystem] resetLocalization]

@interface LocalizationSystem : NSObject {
    NSString *language;
}


+ (LocalizationSystem *)sharedLocalSystem;

//gets the string localized
- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)comment;

//sets the language
- (void) setLanguage:(NSString*) language;

//gets the current language
- (NSString*) getLanguage;

//resets this system.
- (void) resetLocalization;

@end

LocalizationSystem.m ===

#import "LocalizationSystem.h"

@implementation LocalizationSystem

//Singleton instance
static LocalizationSystem *_sharedLocalSystem = nil;

//Current application bundle to get the languages.
static NSBundle *bundle = nil;

+ (LocalizationSystem *)sharedLocalSystem{
    @synchronized([LocalizationSystem class])
    {
        if (!_sharedLocalSystem){
            [[self alloc] init];
        }
        return _sharedLocalSystem;
    }
    // to avoid compiler warning
    return nil;
}

+(id)alloc{
    @synchronized([LocalizationSystem class])
    {
        NSAssert(_sharedLocalSystem == nil, @"Attempted to allocate a second instance of a singleton.");
        _sharedLocalSystem = [super alloc];
        return _sharedLocalSystem;
    }
    // to avoid compiler warning
    return nil;
}

- (id)init{
    if ((self = [super init])) 
    {
        //empty.
        bundle = [NSBundle mainBundle];
    }
    return self;
}

// Gets the current localized string as in NSLocalizedString.

- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)comment{
    return [bundle localizedStringForKey:key value:comment table:nil];
}

// If this function is not called it will use the default OS language.
// If the language does not exists y returns the default OS language.
- (void) setLanguage:(NSString*) l{
    NSLog(@"preferredLang: %@", l);

    NSString *path = [[ NSBundle mainBundle ] pathForResource:l ofType:@"lproj" ];


    if (path == nil)
        //in case the language does not exists
        [self resetLocalization];
    else
        bundle = [[NSBundle bundleWithPath:path] retain];

    [[NSUserDefaults standardUserDefaults] setObject: [NSArray arrayWithObjects:l, nil] forKey:@"AppleLanguages"];
}

// Just gets the current setted up language.
// returns "es","fr",...
//
// example call:
// NSString * currentL = LocalizationGetLanguage;
- (NSString*) getLanguage{

    NSArray* languages = [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleLanguages"];

    NSString *preferredLang = [languages objectAtIndex:0];

    return preferredLang;
}

// Resets the localization system, so it uses the OS default language.
//
// example call:
// LocalizationReset;
- (void) resetLocalization{
    bundle = [NSBundle mainBundle];
}


@end

あなたが言ったように、このコードは完全に機能します。それは私のために働きました、そしてあなたがチェックしたいなら、そのゲームは今アプリストアでライブです(HueShapes)。

于 2012-12-04T10:36:44.630 に答える
0

たまたまNSUserDefaultsを使用して、言語に関連するものを保存しますか?

SimulatorAppディレクトリ->ライブラリ->設定->を調べます<YourAppBundleName>.plist

言語を設定するNSUserDefaultsメソッドの説明については、NSLocalizedStringに特定の言語を使用させる方法を参照してください。

おそらく、言語を保存するだけで、検出は保存された値を返すだけです。

于 2012-11-30T09:13:00.327 に答える