Xamarin.iOS でのローカライズ
このドキュメントでは、iOS SDK のローカライズ機能と、Xamarin でそれらにアクセスする方法について説明します。
Unicode 以外のデータを処理する必要があるアプリケーションに文字セット/コード ページを含める手順については、国際化エンコードを参照してください。
iOS プラットフォーム機能
このセクションでは、iOS のローカライズ機能の一部について説明します。 特定のコードと例を確認するには、次のセクションに進んでください。
言語
ユーザーは、設定アプリで自分の言語を選択します。 この設定は、オペレーティング システムとアプリで表示される言語文字列とイメージに影響します。
アプリで使用されている言語を確認するには、 NSBundle.MainBundle.PreferredLocalizations
の最初の要素を取得します。
var lang = NSBundle.MainBundle.PreferredLocalizations[0];
この値は、英語の場合は en
、スペイン語の場合は es
、日本語の場合は ja
などの言語コードになります。返される値は、アプリケーションでサポートされているローカライズのいずれかに制限されます (フォールバック ルールを使用して最適な一致を判断します)。
アプリケーション コードでは常にこの値を確認する必要はありません。Xamarin と iOS の両方で、ユーザーの言語に対して正しい文字列またはリソースを自動的に提供するのに役立つ機能が提供されます。 これらの機能については、このドキュメントの残りの部分で説明します。
Note
NSLocale.PreferredLanguages
を使用して、アプリでサポートされているローカライズに関係なく、ユーザーの言語設定を決定します。 このメソッドによって返される値は、iOS 9 で変更されました。詳細については、テクニカル ノート TN2418 を参照してください。
ロケール
ユーザーは、設定アプリで自分のロケールを選択します。 この設定は、日付、時刻、数値、通貨の書式設定方法に影響します。
これにより、ユーザーは 12 時間形式と 24 時間形式のどちらを表示するか、小数点がコンマかポイントか、日付表示の日、月、年の順序を選択できます。
Xamarin を使用すると、Apple の iOS クラス (NSNumberFormatter
) と System.Globalization の .NET クラスの両方にアクセスできます。 開発者は、それぞれの機能が異なるので、ニーズに適しているかを評価する必要があります。 特に、StoreKit を使用してアプリ内購入価格を取得して表示する場合は、返される価格情報に Apple’の書式設定クラスを使用する必要があります。
現在のロケールは、次の 2 つの方法のいずれかで照会できます。
NSLocale.CurrentLocale.LocaleIdentifier
NSLocale.AutoUpdatingCurrentLocale.LocaleIdentifier
最初の値はオペレーティング システムによってキャッシュできるため、ユーザーの現在選択されているロケールが常に反映されるとは限りません。 現在選択されているロケールを取得するには、2 番目の値を使用します。
Note
Mono (Xamarin.iOS のベースとなる .NET ランタイム) と Apple の iOS API では、同じ言語とリージョンの組み合わせがサポートされていません。 このため、iOS 設定アプリで、Mono の有効な値にマップされない言語と地域の組み合わせを選択する可能性があります。 たとえば、iPhone の言語を英語に設定し、その地域をスペインに設定すると、次の API によって異なる値が生成されます。
CurrentThead.CurrentCulture
: en-US (Mono API)CurrentThread.CurrentUICulture
: en-US (Mono API)NSLocale.CurrentLocale.LocaleIdentifier
: en_ES (Apple API)
Mono では CurrentThread.CurrentUICulture
を使用してリソースを選択し、 CurrentThread.CurrentCulture
を使用して日付と通貨を書式設定するため、Mono ベースのローカライズ (.resx ファイルなど) では、これらの言語と地域の組み合わせに対して期待される結果が得られない可能性があります。 このような状況では、必要に応じてローカライズするために Apple の API に依存します。
NSCurrentLocaleDidChangeNotification
ユーザーがロケールを更新すると、iOS によって NSCurrentLocaleDidChangeNotification
が生成されます。 アプリケーションは、実行中にこの通知をリッスンし、UI に適切な変更を加えることができます。
iOS でのローカライズの基本
次の iOS の機能は、ユーザーに表示するローカライズされたリソースを提供するために、Xamarin で簡単に利用できます。 これらのアイデアを実装する方法については、TaskyL10n サンプルを参照してください。
Info.plist での既定の言語とサポートされている言語の指定
Apple は、Technical Q&A QA1828: How iOS Determines the Language For Your App で、iOS がアプリで使用する言語を選択する方法について説明しています。 表示される言語に影響を与える要因は次のとおりです。
- ユーザーの優先言語 (設定アプリにあります)
- アプリにバンドルされているローカライズ (.lproj フォルダー)
CFBundleDevelopmentRegion
(アプリの既定の言語を指定する Info.plist 値)CFBundleLocalizations
(サポートされているすべてのローカライズを指定する Info.plist 配列)
テクニカル Q&A で示されているように、CFBundleDevelopmentRegion
はアプリの既定のリージョンと言語を表します。 アプリがユーザーの優先言語を明示的にサポートしない場合は、このフィールドで指定された言語が使用されます。
重要
iOS 11 では、オペレーティング システムの以前のバージョンよりも厳密にこの言語選択メカニズムが適用されます。 このため、サポートされているローカライズを明示的に宣言していない iOS 11 アプリでは、.lproj フォルダーを含めるか値 CFBundleLocalizations
を設定することで、iOS 11 では iOS 10 とは異なる言語が表示される可能性があります。
Info.plist ファイルで CFBundleDevelopmentRegion
が指定されていない場合、Xamarin.iOS ビルド ツールでは現在、既定値の en_US
が使用されます。 これは将来のリリースで変更される可能性があります。これは、既定の言語が英語であることを意味します。
アプリで想定される言語が選択されていることを確認するには、次の手順を実行します。
- 既定の言語を指定します。 Info.plist を開き、ソース ビューを使用して、
CFBundleDevelopmentRegion
キーの値を設定します。XML では、次のようになります。
<key>CFBundleDevelopmentRegion</key>
<string>es</string>
この例では、"es" を使用して、ユーザーの優先言語がサポートされない場合に、既定でスペイン語に設定します。
- サポートされているすべてのローカライズを宣言します。 Info.plist で、ソース ビューを使用して、
CFBundleLocalizations
キーの配列を設定します。XML では、次のようになります。
<key>CFBundleLocalizations</key>
<array>
<string>en</string>
<string>es</string>
...
</array>
.resx ファイルなどの .NET メカニズムを使用してローカライズされた Xamarin.iOS アプリは、これらの Info.plist 値も提供する必要があります。
これらの Info.plist キーの詳細については、Apple の Information Property List Key Reference を参照してください。
GetLocalizedString メソッド
NSBundle.MainBundle.GetLocalizedString
メソッドは、プロジェクト内の .strings ファイルに格納されているローカライズされたテキストを検索します。 これらのファイルは、.lproj サフィックスを持つ特別な名前のディレクトリで言語別に整理されます (拡張子の最初の文字は小文字の "L" であることに注意してください)。
.strings ファイルの場所
- Base.lproj は、既定の言語のリソースを含むディレクトリです。 多くの場合、プロジェクト ルートにあります (ただし、Resources フォルダーに配置することもできます)。
- <language>.lproj ディレクトリは、サポートされている各言語 (通常は Resources フォルダー内) に作成されます。
各言語ディレクトリには、さまざまな .strings ファイルが存在する可能性があります。
- Localizable.strings – ローカライズされたテキストのメイン リスト。
- InfoPlist.strings – このファイル内の特定のキーを使用して、アプリケーション名などの翻訳を行えます。
- <storyboard-name>.strings – ストーリーボード内のユーザー インターフェイス要素の翻訳を含む省略可能なファイル。
これらのファイルのビルド アクションは、バンドル リソースである必要があります。
.strings ファイル形式
ローカライズされた文字列値の構文は次のとおりです。
/* comment */
"key"="localized-value";
文字列内の次の文字をエスケープする必要があります。
\"
のクォート\\
バックスラッシュ\n
改行
これは、サンプルのes/Localizable.strings (つまり、スペイン語) ファイルの例です。
"<new task>" = "<new task>";
"Task Details" = "Detalles de la tarea";
"Name" = "Nombre";
"task name" = "nombre de la tarea";
"Notes" = "Notas";
"other task info"= "otra información de tarea";
"Done" = "Completo";
"Save" = "Guardar";
"Delete" = "Eliminar";
Images
iOS でイメージをローカライズするには:
コード内のイメージを参照してください。次に例を示します。
UIImage.FromBundle("flag");
既定のイメージ ファイル flag.png を Base.lproj (ネイティブ開発言語ディレクトリ) に配置します。
必要に応じて、各言語の .lproj フォルダー (例: es.lproj、ja.lproj) にローカライズされたバージョンのイメージを配置します。 各言語ディレクトリで同じファイル名 flag.png を使用します。
特定の言語にイメージが存在しない場合、iOS は既定のネイティブ言語フォルダーにフォールバックし、そこからイメージを読み込みます。
起動画面
各言語の .lproj ディレクトリに配置するときは、起動イメージ (および iPhone 6 モデルの場合は XIB またはストーリーボード) の標準の名前付け規則を使用します。
Default.png
Default@2x.png
Default-568h@2x.png
LaunchScreen.xib
アプリ名
.lproj ディレクトリに InfoPlist.strings ファイルを配置すると、アプリケーション名など、アプリの Info.plist の一部の値をオーバーライドできます。
"CFBundleDisplayName" = "LeónTodo";
アプリケーション固有の文字列をローカライズするために使用できるその他のキーは次のとおりです。
- CFBundleName
- CFBundleShortVersionString
- NSHumanReadableCopyright
日付と時刻
組み込みの .NET 日時関数 (現在の CultureInfo
と共に) を使用してロケールの日付と時刻を書式設定することはできますが、ロケール固有のユーザー設定 (言語とは別に設定できます) は無視されます。
iOS NSDateFormatter
を使用して、ユーザーのロケール設定に一致する出力を生成します。 次のサンプル コードは、基本的な日付と時刻の書式設定オプションを示しています。
var date = NSDate.Now;
var df = new NSDateFormatter ();
df.DateStyle = NSDateFormatterStyle.Full;
df.TimeStyle = NSDateFormatterStyle.Long;
Debug.WriteLine ("Full,Long: " + df.StringFor(date));
df.DateStyle = NSDateFormatterStyle.Short;
df.TimeStyle = NSDateFormatterStyle.Short;
Debug.WriteLine ("Short,Short: " + df.StringFor(date));
df.DateStyle = NSDateFormatterStyle.Medium;
df.TimeStyle = NSDateFormatterStyle.None;
Debug.WriteLine ("Medium,None: " + df.StringFor(date));
米国の英語の結果:
Full,Long: Friday, August 7, 2015 at 10:29:32 AM PDT
Short,Short: 8/7/15, 10:29 AM
Medium,None: Aug 7, 2015
スペインのスペイン語の結果:
Full,Long: viernes, 7 de agosto de 2015, 10:26:58 GMT-7
Short,Short: 7/8/15 10:26
Medium,None: 7/8/2015
詳細については、Apple の日付フォーマッタドキュメントを参照してください。 ロケールに依存する日付と時刻の書式設定をテストする場合は、iPhone の言語とリージョン設定の両方を確認します。
右から左 (RTL) のレイアウト
iOS には、RTL 対応アプリの構築に役立つさまざまな機能が用意されています。
- コントロールの配置には、自動レイアウトの
leading
属性とtrailing
属性を使用します (これは英語では左右に対応しますが、RTL 言語では逆になります)。UIStackView
コントロールは、RTL 対応のコントロールをレイアウトする場合に特に便利です。 - テキストの配置には
TextAlignment = UITextAlignment.Natural
を使用します (ほとんどの言語の場合は左、RTL の場合は右)。 UINavigationController
は、戻るボタンを自動的に反転し、スワイプの方向を反転します。
次のスクリーンショットは、アラビア語とヘブライ語のローカライズされた Tasky サンプルを示しています (ただし、フィールドには英語が入力されています)。
iOS は自動的に UINavigationController
を反転し、他のコントロールは UIStackView
内に配置されるか、自動レイアウトに合わせて配置されます。
RTL テキストは、LTR テキストと同じ方法で .strings ファイルを使用してローカライズされます。
コードでの UI のローカライズ
Tasky (コード内でローカライズ) サンプルは、ユーザー インターフェイスが (XIB やストーリーボードではなく) コードでビルドされているアプリケーションをローカライズする方法を示しています。
プロジェクト構造
Localizable.strings ファイル
前述のように、Localizable.strings ファイル形式はキーと値のペアで構成されます。 キーは文字列の意図を表し、値はアプリで使用される翻訳されたテキストです。
サンプルのスペイン語 (es) のローカライズを次に示します。
"<new task>" = "<new task>";
"Task Details" = "Detalles de la tarea";
"Name" = "Nombre";
"task name" = "nombre de la tarea";
"Notes" = "Notas";
"other task info"= "otra información de tarea";
"Done" = "Completo";
"Save" = "Guardar";
"Delete" = "Eliminar";
ローカライズの実行
アプリケーション コードでは、ユーザー インターフェイスの表示テキストが設定されている場所 (ラベルのテキスト、入力のプレースホルダーなどが設定されている場所)で、コードは iOS GetLocalizedString
関数を使用して正しい翻訳を取得して表示します。
var localizedString = NSBundle.MainBundle.GetLocalizedString ("key", "optional");
someControl.Text = localizedString;
ストーリーボード UI のローカライズ
サンプルの Tasky (ローカライズされたストーリーボード) は、ストーリーボード内のコントロールのテキストをローカライズする方法を示しています。
プロジェクト構造
Base.lproj ディレクトリにはストーリーボードが含まれており、アプリケーションで使用されるイメージも含まれている必要があります。
他の言語ディレクトリには、コードで参照されるすべての文字列リソースの Localizable.strings ファイルと、ストーリーボード内のテキストの翻訳を含む MainStoryboard.strings ファイルが含まれています。
言語ディレクトリには Base.lproj に存在するイメージをオーバーライドするために、ローカライズされたイメージのコピーが含まれている必要があります。
オブジェクト ID/ローカライズ ID
ストーリーボードでコントロールを作成および編集する場合は、各コントロールを選択し、ローカライズに使用する ID を確認します。
- Visual Studio for Mac では、Properties Pad に配置され、ローカライズ ID と呼ばれます。
- Xcode では、オブジェクト ID と呼ばれます。
この文字列値には、多くの場合、次のスクリーンショットに示すように、"NF3-h8-xmR" などの形式があります。
この値は、翻訳されたテキストを各コントロールに自動的に割り当てるために、.strings ファイルで使用されます。
MainStoryboard.strings
ストーリーボード翻訳ファイルの形式は Localizable.strings ファイルに似ていますが、キー (左側の値) をユーザー定義にすることはできませんが、代わりに非常に具体的な形式 ObjectID.property
である必要があります。
以下の Mainstoryboard.strings の例では、UITextField
にローカライズ可能な placeholder
テキスト プロパティがあり、UILabel
には text
プロパティがあり、 UIButton
の既定のテキストは normalTitle
を使用して設定されることがわかります。
"SXg-TT-IwM.placeholder" = "nombre de la tarea";
"Pqa-aa-ury.placeholder"= "otra información de tarea";
"zwR-D9-hM1.text" = "Detalles de la tarea";
"bAM-2j-Rzw.text" = "Notas"; /* Notes */
"NF3-h8-xmR.text" = "Completo"; /* Done */
"MWt-Ya-pMf.normalTitle" = "Guardar"; /* Save */
"IGr-pR-05L.normalTitle" = "Eliminar"; /* Delete */
重要
サイズ クラスでストーリーボードを使用すると、アプリケーションに表示されない翻訳が発生する可能性があります。 Apple の Xcode リリース ノート では、ストーリーボードまたは XIB は、サイズ クラスを使用し、ベース ローカライズとビルド ターゲットがユニバーサルに設定され、ビルドターゲットが iOS 7.0 をターゲットとする 3 つの場合、正しくローカライズされないことを示しています。 次のスクリーンショットに示すように、ストーリーボード文字列ファイルを 2 つの同じファイル (MainStoryboard~iphone.strings と MainStoryboard~ipad.strings) に複製します。
App Store の一覧
App Store のローカライズに関する Apple の FAQ に従って、アプリが販売されている各国の翻訳を入力します。 翻訳は、アプリに言語のローカライズされた .lproj ディレクトリも含まれている場合にのみ表示されるという警告に注意してください。
まとめ
この記事では、組み込みのリソース処理機能とストーリーボード機能を使用した iOS アプリケーションのローカライズの基本について説明します。
iOS、Android、クロスプラットフォーム アプリ (Xamarin.Forms を含む) の i18n と L10n の詳細については、このクロスプラットフォーム ガイドを参照してください。