【XCode】端末の言語設定から言語コードを取得する方法によって結果が異なる問題

仕事が久々のiOSアプリの開発になりまして

iPhone5sの頃くらいぶりの仕事ゆえ調べることが多いです


さて、今回はWebAPIを実行するときに言語IDを付与する必要があり

そのために端末の言語設定を取得して判定をすることを調べたときに

取得方法によって結果が異なることがわかったのでメモします。


取得方法は以下のやり方で行いました。


NSString* lan1 = [NSLocale currentLocale].localeIdentifier;

NSString* lan2 = [NSLocale preferredLanguages].firstObject;

NSString* lan3 = [[NSLocale localeWithLocaleIdentifier:lan2] languageCode];


NSArray* languages = [[NSBundle mainBundle]preferredLocalizations];

NSString* lan4 = [languages objectAtIndex:0];


lan1~lan4の結果を以下の条件で各々みてみましょう


Info.plistのLocalization native development region: 日本語
アプリのローカライズ対応言語: 日本語、英語(米)、中国語(簡体)
端末の地域設定 日本

◆端末の言語設定 日本語の場合
lan1: ja_JP
lan2: ja-JP
lan3: ja
languages: ja_JP, ja
lan4: ja_JP

languagesでja_JPとjaの2つ取得できている理由はよくわかりません
NSLocale currentLocaleではアンダースコア”_”
NSLocale preferredLanguagesではハイフン”-”で言語コードと国コードが接続されています

◆端末の言語設定 Englishの場合
lan1: en_JP
lan2: en-JP
lan3: en
languages: en
lan4: en

言語コードと国コードが取得できるので
このような結果を取得できます
「言語コード」だけがほしい場合はlan3かlan4をみたほうがよさそうですね
ただ、日本語の例のようにjaがとれる保証はないという結果

◆端末の言語設定 簡体中国語の場合
lan1: zh-Hans_JP
lan2: zh-Hans-JP
lan3: zh
languages: zh-Hans
lan4: zh-Hans

中国語は簡体と繁体の2種類があります
lan3だと「中国語」コードとなってしまい、簡体と繁体の区別ができません
lan4ではしっかりとは区別することができます

ここまでアプリのローカライズ対応の言語に対し端末の言語を設定した場合の結果です。


◆端末の言語設定 繁体中国語の場合
lan1: zh-Hant_JP
lan2: zh-Hant-JP
lan3: zh
languages: zh-Hant
lan4: zh-Hant

簡体で説明したようにlan3では簡体繁体の区別ができません
sとtの違いで区別するようですね

◆端末の言語設定 ドイツ語の場合(完全非対応言語)
lan1: ja_JP
lan2: de-JP
lan3: de
languages: ja_JP, ja
lan4: ja_JP

どうしてこうなった!
と思ってしまった結果でした。
NSLocale preferredLanguagesだけ端末の言語コードを返しています
NSLocale currentLocaleと[NSBundle mainBundle] preferredLocalizationsでは日本語と同じ結果を返しています


こちらの情報よりiOS9からNSLocale preferredLanguagesの結果が言語コード+国コードに変わったという内容
こちらの情報よりiOS11からNSLocale currentLocaleの結果が変わったという内容


今回のプロジェクトではiOS10~をサポートする予定となっているので
NSLocale currentLocaleに関しては注意が必要ですね

●NSLocale currentLocale
iOS10までは端末の言語コードが必ず返していた
iOS11からはアプリ内でローカライズ対応している言語コードの中から必ず返される
→今回の例でいう日本語、英語、中国語の3言語以外を端末の言語コードに指定している場合、
 ドイツ語の結果のように基本言語に選択している言語コードが取得できる・・・ということでしょうかね

ローカライズ言語に対応していない言語の場合、デフォルトの言語とみなして~っという判定をパスして
システムがデフォルト言語に指定しているコードを返してくれていると考えて実装していきましょう

でもiOS10のときだけ挙動が違うので判定処理は必要か…

この記事へのコメント