1. ホーム
  2. ios

iOSアプリの手動言語選択 (iPhone、iPad)

2023-11-16 11:32:44

質問

私の質問です。

私の iPhone アプリは、ユーザーがアプリの環境設定で、一般設定で設定された言語とは異なる言語を選択したことを、どのようにして iOS に伝えることができますか?

同じ質問に対する他の表現。

どのようにすれば、システムに NSLocalizedString (@"text", @"comment"); はシステム全体で選択された言語ではなく、アプリ内で選択された言語にアクセスするようにシステムに指示できますか?

の背景、例です。

このような状況を例にとって考えてみましょう。 あるドイツ系移民の息子は、ルクセンブルクとドイツに隣接するフランスの北東部に住んでいます。彼の母国語はフランス語なので、iPhone のユーザー インターフェイスの言語をフランス語に設定しました (設定 → 一般 → 国際 → 言語 → Français)。しかし、彼の文化的背景と住んでいる地域がバイリンガルであることから、ドイツ語も非常によく話します。しかし、英語は10語も話せません。iPhone(iPadも同様)では、第二言語を選択する機会がないため、携帯電話は彼がフランス語を話していることだけを知っています。iPhone (および iPad も同様) では、第二言語を選択する機会がないため、携帯電話は、彼がフランス語を話していることだけを知っています。

次に、私のアプリです。英語とドイツ語で開発しました (ドイツ語は私の母国語、英語は IT 業界の標準言語です)。多言語の iOS アプリのすべてのルールとベスト プラクティスに従って開発しました。

ということです。

誰かが設定で英語またはドイツ語を選択した場合、アプリのユーザー インターフェイスは自動的に選択された言語を使用します。ユーザーは、他の言語が利用可能であることに気づきません。

しかし、一般的な設定で他の言語 (中国語、ポーランド語、フランス語など) を選択した場合は、アプリのデフォルト言語が使用され、私の場合は英語となります。しかし、私のフランス語とドイツ語の友人にとって、これは最良の選択ではありません。彼は既存のドイツ語版を使用したいようですが、ユーザーがこのバージョンを選択できるようにする方法はないようです。

フランス語の翻訳を追加すれば、フランス語とドイツ語の友人の問題は解決しますが、他の 2 つの言語 (イタリア語とドイツ語など) を話す人の問題は解決しませんし、この地球上で話されているすべての言語で私のアプリをサポートすることはできません。 デフォルトの言語をドイツ語に設定することも最適とは言えません。

そこで、私のアプリでは、あらかじめ選択されている言語とは異なる言語を手動で選択できるようにする必要があると思います。アプリの設定パネルに言語選択を追加することは問題ではありません。しかし、どのようにして、システムに NSLocalizedString (@"text", @"comment"); は、システム全体で選択された言語ではなく、アプリ内で選択された言語にアクセスするようにシステムに指示できますか?

どのように解決するのですか?

とりあえず、自分なりに解決策を見つけました。

私は新しいクラス "LocalizeHelper"を作成しました。


ヘッダ LocalizeHelper.h

//LocalizeHelper.h

#import <Foundation/Foundation.h>

// some macros (optional, but makes life easy)

// Use "LocalizedString(key)" the same way you would use "NSLocalizedString(key,comment)"
#define LocalizedString(key) [[LocalizeHelper sharedLocalSystem] localizedStringForKey:(key)]

// "language" can be (for american english): "en", "en-US", "english". Analogous for other languages.
#define LocalizationSetLanguage(language) [[LocalizeHelper sharedLocalSystem] setLanguage:(language)]

@interface LocalizeHelper : NSObject

// a singleton:
+ (LocalizeHelper*) sharedLocalSystem;

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

//set a new language:
- (void) setLanguage:(NSString*) lang;              

@end


iMplementation LocalizeHelper.m

// LocalizeHelper.m
#import "LocalizeHelper.h"

// Singleton
static LocalizeHelper* SingleLocalSystem = nil;

// my Bundle (not the main bundle!)
static NSBundle* myBundle = nil;


@implementation LocalizeHelper


//-------------------------------------------------------------
// allways return the same singleton
//-------------------------------------------------------------
+ (LocalizeHelper*) sharedLocalSystem {
    // lazy instantiation
    if (SingleLocalSystem == nil) {
        SingleLocalSystem = [[LocalizeHelper alloc] init];
    }
    return SingleLocalSystem;
}


//-------------------------------------------------------------
// initiating
//-------------------------------------------------------------
- (id) init {
    self = [super init];
    if (self) {
        // use systems main bundle as default bundle
        myBundle = [NSBundle mainBundle];
    }
    return self;
}


//-------------------------------------------------------------
// translate a string
//-------------------------------------------------------------
// you can use this macro:
// LocalizedString(@"Text");
- (NSString*) localizedStringForKey:(NSString*) key {
    // this is almost exactly what is done when calling the macro NSLocalizedString(@"Text",@"comment")
    // the difference is: here we do not use the systems main bundle, but a bundle
    // we selected manually before (see "setLanguage")
    return [myBundle localizedStringForKey:key value:@"" table:nil];
}


//-------------------------------------------------------------
// set a new language
//-------------------------------------------------------------
// you can use this macro:
// LocalizationSetLanguage(@"German") or LocalizationSetLanguage(@"de");
- (void) setLanguage:(NSString*) lang {

    // path to this languages bundle
    NSString *path = [[NSBundle mainBundle] pathForResource:lang ofType:@"lproj" ];
    if (path == nil) {
        // there is no bundle for that language
        // use main bundle instead
        myBundle = [NSBundle mainBundle];
    } else {

        // use this bundle as my bundle from now on:
        myBundle = [NSBundle bundleWithPath:path];

        // to be absolutely shure (this is probably unnecessary):
        if (myBundle == nil) {
            myBundle = [NSBundle mainBundle];
        }
    }
}


@end


サポートしたい言語ごとに Localizable.strings . これは Apple のローカライゼーションのドキュメントで説明されているのと全く同じように動作します。唯一の違いは。Apple がサポートしていないヒンディー語やエスペラント語のような言語も使用できるようになったことです。

例を挙げると、私の英語版とドイツ語版の Localizable.strings の最初の行がここにあります。

英語

/* English - English */

/* for debugging */
"languageOfBundle" = "English - English";

/* Header-Title of the Table displaying all lists and projects */
"summary" = "Summary";

/* Section-Titles in table "summary" */
"help" = "Help";
"lists" = "Lists";
"projects" = "Projects";
"listTemplates" = "List Templates";
"projectTemplates" = "Project Templates";

ドイツ語

/* German - Deutsch */

/* for debugging */
"languageOfBundle" = "German - Deutsch";

/* Header-Title of the Table displaying all lists and projects */
"summary" = "Überblick";

/* Section-Titles in table "summary" */
"help" = "Hilfe";
"lists" = "Listen";
"projects" = "Projekte";
"listTemplates" = "Vorlagen für Listen";
"projectTemplates" = "Vorlagen für Projekte";


ローカライズを使用するには、アプリにいくつかの設定ルーチンがあり、言語選択でマクロを呼び出す必要があります。

LocalizationSetLanguage(selectedLanguage);

その後、旧言語で表示されていたものがすべて新言語で再描画されることを確認する必要があります(非表示のテキストは、再び表示されるようになったらすぐに再描画する必要があります)。

あらゆる状況でローカライズされたテキストを利用できるようにするために、オブジェクトのタイトルに固定テキストを記述する必要はありません。常にマクロ LocalizedString(keyword) .

はやめてください。

cell.textLabel.text = @"nice title";

してください。

cell.textLabel.text = LocalizedString(@"nice title");

そして、Localizable.strings の全てのバージョンに "nice title" というエントリを持つようにしましょう!