Flutterの日本語のみ対応アプリに英語対応を追加してみる
Dartのバージョンは3系を利用中。
まずは以下をもとにFlutter側の多言語対応する。
pubspec.yaml
に以下が記載されていることを確認。
# ...
dependencies:
# ...
flutter_localizations:
sdk: flutter
# ...
intl: 0.18.1
# ...
大元のMaterialApp
を修正。
return MaterialApp(
// ...
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [
+ Locale('en'),
Locale('ja', 'JP'),
],
// ...
);
pubspec.yaml
に generate
を追加。
// ...
flutter:
uses-material-design: true
+ generate: true
// ...
lib/l10n/app_en.arb
と lib/l10n/app_ja.arb
を作成し、以下のように作成。
{
"appTitle": "App title"
}
{
"appTitle": "アプリタイトル"
}
この状態で一旦アプリをデバッグ実行し、${FLUTTER_PROJECT}/.dart_tool/flutter_gen/gen_l10n
が生成された状態にする。
ローカライゼーションのデリゲートを追加する。自動生成されているものを指定する。
+import 'package:flutter_gen/gen_l10n/app_localizations.dart';
// ...
return MaterialApp(
// ...
- localizationsDelegates: const [
- GlobalMaterialLocalizations.delegate,
- GlobalWidgetsLocalizations.delegate,
- GlobalCupertinoLocalizations.delegate,
- ],
+ localizationsDelegates: AppLocalizations.localizationsDelegates,
- supportedLocales: const [
- Locale('en'),
- Locale('ja', 'JP'),
- ],
+ supportedLocales: AppLocalizations.supportedLocales,
// ...
);
あとは、元々直書きしてあった日本語のテキストにラベルのキー名を定義しつつ lib/l10n/app_ja.arb
に転記し、lib/l10n/app_en.arb
に英語版を定義していく。
日本語で 保存期限: 2024/3/1
のようになっているところは、英語で Accessible until 1/3/2024
のようにしてみた。
日付の部分 1/3/2024
は、Intlのパッケージが自動で変換している。
1.03秒
みたいな、小数点第n位まで表示する+多言語化する文字列という構造は以下のように整理するのが良さそう。
- 「小数点第n位まで表示する」部分はDartで実現
- 「小数点第n位まで表示された文字列」を前提に「多言語化する文字列」をarbファイルで表現
{
"@@locale": "ja",
"nSeconds": "{seconds}秒",
"@nSeconds": {
"placeholders": {
"seconds": {
"type": "String"
}
}
}
}
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
// ...
const durationSeconds = 1.03;
final durationSecondsString = durationSeconds.toStringAsFixed(3);
final durationText = Text(
AppLocalizations.of(context)!.nSeconds(durationSecondsString),
style: Theme.of(context).textTheme.bodySmall,
);
文字列の途中に太字を使うようなリッチテキストはarbファイルで表現できないので、多言語化する場合はリッチテキストはやめるのが一番簡単そう。つまり、1パラグラフ中の一部分を太字とするような仕様をやめ、1パラグラフ中の全ての文字は均一のスタイルにする。
Dartの多言語化は完了
あとは以下を対応する必要がある。
- サーバーから取得できるデータ
- 利用規約とプライバシーポリシー
- ストアのメタデータとスクリーンショット
- ストアに登録している課金アイテム
iOSのApp Storeのデータを多言語化する。
まず、ストアに設定済みの日本語のスクリーンショットとメタデータを、ローカルにダウンロードする。
bundle exec fastlane deliver download_screenshots --use_live_version true
App Store上でバージョンを新規作成し、編集中のバージョンが存在する状態にしてから、以下コマンドを実行する。
bundle exec fastlane deliver download_metadata
(記載途中)
AndroidのGoogle Play Storeのデータを多言語化する。
まず、ストアに設定済みの日本語のスクリーンショットとメタデータを、ローカルにダウンロードする。
cd android/
bundle exec fastlane supply init json_key:"fastlane/google-play-service-account-key.json"
(記載途中)
iOSアプリのネイティブに持っているローカライズできる要素を多言語化する。
- アプリの表示名
- ビルド時のIPAファイル名
- 権限取得時のユーザーに表示するメッセージ
以下を元に実施することで問題なくできた。
この際、xcstringsのファイル名は大文字・小文字も厳密に InfoPlist.xcstrings
と一致する必要がある。一致していない場合、多言語化が発動しない。
Androidアプリのネイティブに持っているローカライズできる要素を多言語化する。
- アプリの表示名
app/src/main/res/values-ja/strings.xml
を追加して日本語を定義し、 app/src/main/res/values/strings.xml
に英語を定義しておく。
端末の言語設定に応じた言語コードを取得し、サーバーから取得しているデータの言語データを選択したい。
以下を元にすると、 ja_JP
における言語コード ja
部分は取得できるが、国コード JP
部分が null
になって取得できない。
final locale = Localizations.localeOf(context);
debugPrint(
'Locale ${locale.toLanguageTag()} '
'Language code: ${locale.languageCode}, '
'Country code: ${locale.countryCode}',
);
I/flutter (10831): Language tag: ja Language code: ja, Country code: null
以下のようにすると取得できた。
-final locale = Localizations.localeOf(context);
+final locale = WidgetsBinding.instance.platformDispatcher.locale;
debugPrint(
'Language tag: ${locale.toLanguageTag()} '
'Language code: ${locale.languageCode}, '
'Country code: ${locale.countryCode}',
);
I/flutter (10831): Language tag: ja-JP Language code: ja, Country code: JP
デバイスロケールの変化をリアルタイムに取得するためには、 MaterialApp
の中のウィジェットで、didChangeDependencies
のイベントを利用する。
MaterialApp
と同列の didChangeDependencies
では変化がキャッチできない。
アプリ内購入の定期購読アイテムは、Fastlaneの標準のストア管理レーンである deliver
や supply
では更新・新規登録できなさそう。
iOSのApp Storeに関しては、以下を利用することでできそう。
言語設定だけでなく、世界中で利用できるようにする場合は、以下のような地域によって変化する概念に関しても整理が必要。
- 時刻
- 曜日
- ものの単位(温度、重さとか)
リリースごとに各言語のリリースノートを準備する必要がある。
ストアのメタデータに関しては、以下がローカライズデータの必須情報
iOS
項目 | fastlane のファイル名 |
---|---|
アプリ情報 > 名前 | fastlane/metadata/en-US/name.txt |
アプリ情報 > サブタイトル | fastlane/metadata/en-US/subtitle.txt |
バージョン > 概要 | fastlane/metadata/en-US/description.txt |
バージョン > このバージョンの最新情報 | fastlane/metadata/en-US/release_notes.txt |
バージョン > キーワード | fastlane/metadata/en-US/keywords.txt |
バージョン > サポート URL | fastlane/metadata/en-US/support_url.txt |
Android
項目 | fastlane のファイル名 |
---|---|
メインのストアの掲載情報 > アプリ名 | fastlane/metadata/en-US/title.txt |
メインのストアの掲載情報 > 簡単な説明 | fastlane/metadata/en-US/short_description.txt |
メインのストアの掲載情報 > 詳しい説明 | fastlane/metadata/en-US/full_description.txt |
製品版 > リリースノート | fastlane/metadata/en-US/changelogs/default.txt |
ストアのプライマリ言語を英語に変えた方がいい
iOSでは、一旦英語版のスクリーンショットを提出して審査通す必要がありそう。