31
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

iOSの言語設定を取得するベストプラクティス(Swift)

はじめに

iOSの言語設定を取得するベストプラクティスを紹介します。

環境

PC

  • OS:macOS Big Sur 11.0.1
  • Xcode:12.2 (12B45b)
  • Swift:5.3.1

シミュレータ

  • 機種:iPhone SE (2nd generation)
  • OS:iOS 14.2

結論

  • アプリがローカライズされていない
    • Locale.current ではうまく取得できないので、 Locale.preferredLanguages から Locale を生成し直す
  • アプリがローカライズされている
    • アプリ単位で優先する言語を指定できるので、「おまけ」に書いたようにローカライズの設定を使うのがベター
    • OS単位の言語設定を取得したい場合は、ローカライズされていないときと同様の方法でいい

言語設定の取得を試す

結論に至るまでにいろいろ試したので、過程を紹介します。

PREFERRED LANGUAGE ORDER(使用する言語の優先順序): English > 日本語 (アメリカ)
地域: United States(アメリカ合衆国)

まずはシミュレータのデフォルト設定で試してみます。

Language & Region(言語と地域)
プロパティ 戻り値
Locale.preferredLanguages ["en", "ja-US"]
Locale.current.description en (current)
Locale.current.languageCode en
Locale.current.regionCode nil

ほぼ予想通りの結果ですが、 ja-US という表記を初めて見たのと、 regionCodenil なのは意外でした。

使用する言語の優先順序: 日本語 > English
地域: アメリカ合衆国

次に、使用する言語の優先順序を入れ替えます。
地域は英語→日本語表記になったので変わったように見えますが、変えていません。

Language & Region(言語と地域)
プロパティ 戻り値
Locale.preferredLanguages ["ja-US", "en"]
Locale.current.description en_US (current)
Locale.current.languageCode en
Locale.current.regionCode US

Locale.preferredLanguages が入れ替わったのは予想通りでしたが、他は私の中では予想外でした。
優先順序を入れ替えたことによって「iPhoneの使用言語」が 日本語 に変わったので、 Locale.current.○○ のプロパティも日本になると思いました。

使用する言語の優先順序: 日本語 > English
地域: 日本

使用する言語の優先順序をそのままに、地域を日本に変えます。

Language & Region(言語と地域)
プロパティ 戻り値
Locale.preferredLanguages ["ja-JP", "en-JP"]
Locale.current.description en_JP (current)
Locale.current.languageCode en
Locale.current.regionCode JP

なんかいろいろおかしい気がしますw
シミュレータだからなのか、言語や地域の変更後に再起動していないからなのか、原因はわかりません。
正しい挙動という可能性ももちろんあります。

おわりに

いろいろ試してもよくわかりませんでした。
何となくわかったのが、 preferredLanguages の要素は {languageCode}-{regionCode} で構成されているということです。

iOSの言語と地域について詳しい方がいたら、コメントなどで教えていただけると嬉しいです :relaxed:

追記:
Twitter でAppleの公式ドキュメントを教えていただきました。
言語IDやロケールIDについて詳しく書いてあるので、こちらを読めば深く理解できそうです。
https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPInternational/LanguageandLocaleIDs/LanguageandLocaleIDs.html#//apple_ref/doc/uid/10000171i-CH15

おまけ:言語設定の取得をローカライズ文字列に任せる

iOSの言語設定がうまく取得できなかったので、代替案を考える必要があります。

Localizable.string"languageCode" = "en"; のようなキーと値を持たせ、言語設定の取得をローカライズ文字列に任せる方法を思いつきましたw
他にいい方法があれば教えてください :sob:

みなさんはアプリ内でなくサーバーから言語設定に応じた文字列を取得する場合、どのように言語設定をサーバーに渡しているのだろう… :thinking:

追記:
@k_katsumi さんにTwitterでいろいろ教えていただきました :pray:

実際に preferredLanguages から Locale を作り直し、各プロパティを確認しました。

print(Locale.preferredLanguages) // ["ja-JP", "en-JP"]

let language = Locale.preferredLanguages.first!
print(language) // ja-JP

let locale = Locale(identifier: language)
print(locale.description) // ja-JP (fixed)
print(locale.languageCode ?? "nil") // ja
print(locale.regionCode ?? "nil") // JP
print(locale.scriptCode ?? "nil") // nil

適切に languageCoderegionCode を取得できました。
自分で生成した Locale だと description の括弧内が (current) でなく (fixed) になるようです。

ローカライズされているアプリは、OS単位でなくアプリ単位でも優先する言語を指定できるので、ローカライズの設定に従うのはベターな方法でした。
おまけとして書きましたが、こちらの方法を採用するのがよさそうです。

@treastrain さんも採用しているとのことです。

参考リンク

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
31
Help us understand the problem. What are the problem?