Flutter SDKでローカリゼーションとロケールコードを使用する

これが重要な理由

ロケールコードは、Adapty がフローのローカライズを選択する際や、カスタムペイウォールのリモートコンフィグを読み取る際に使用されます。

ロケールコードはプラットフォームによって異なる場合があり複雑なため、Adapty はサポートするすべてのプラットフォームで共通の内部標準を採用しています。この標準を理解することで、ユーザーがどのローカライズを受け取るかを予測できます。

Adapty におけるロケールコードの標準

ロケールコードには、Adapty は BCP 47 標準 を少し修正したものを使用しています。各コードは、ハイフンで区切られた小文字のサブタグで構成されます。例: en(英語)、pt-br(ポルトガル語(ブラジル))、zh(簡体字中国語)、zh-hant(繁体字中国語)。

ロケールコードのマッチング

Adapty がユーザーのロケールに合う地域化を探す際、以下の処理が行われます。

  1. ロケール文字列を小文字に変換し、アンダースコア(_)をすべてハイフン(-)に置き換えます
  2. ロケールコードが完全に一致する地域化を検索します
  3. 一致する地域化が見つからない場合、最初のハイフンより前の部分文字列(pt-br に対する pt など)を取り出し、一致する地域化を検索します
  4. それでも一致する地域化が見つからない場合、デフォルトの en 地域化を返します

このため、'pt_BR'pt-BRpt-br はすべて同じ地域化に解決されます。

ローカライズの実装

SDK v4 では、フローを取得する際にロケールコードを渡す必要はありません。

  • フロービルダーおよびペイウォールビルダーのペイウォール: Adapty はデバイス設定とビルダーで設定したローカライズをもとに、自動的にローカライズを解決します。createFlowView でフローをレンダリングするだけで、ロケールコードは不要です。
  • カスタム(リモートコンフィグ)ペイウォール: getFlow は設定されたすべてのローカライズを flow.remoteConfigs に返します。各エントリには locale コードとコンフィグの内容(data 文字列、またはパース済みの dictionary)が含まれています。ユーザーに合ったエントリを選択し、独自のフォールバック処理を実装してください。

final flow = await Adapty().getFlow(placementId: 'YOUR_PLACEMENT_ID');
final config = flow.remoteConfigs.firstWhereOrNull((c) => c.locale == 'en') ??
    flow.remoteConfig; // the first remote config, if present
// read your values from config?.dictionary

上記のロケールコードマッチングルールは、各リモートコンフィグに保存されている locale コードを Adapty がどのように正規化するかを説明しています。

これが重要な理由

ロケールコードが関係するシナリオはいくつかあります。たとえば、アプリの現在のローカライゼーションに合ったペイウォールを取得しようとする場合などです。

ロケールコードはプラットフォームによって異なる場合があり複雑なため、Adapty ではサポートするすべてのプラットフォームで共通の内部標準を採用しています。ただし、コードが複雑であるがゆえに、サーバーに何を送信して正しいローカライゼーションを取得しているのか、そしてその後何が起こるのかを正確に理解しておくことが非常に重要です。そうすることで、期待どおりの結果を常に受け取ることができます。

Adaptyにおけるロケールコードの標準規格

ロケールコードには、AdaptyではBCP 47標準を若干修正したものを採用しています。各コードはハイフンで区切られた小文字のサブタグで構成されます。例:en(英語)、pt-br(ポルトガル語(ブラジル))、zh(簡体字中国語)、zh-hant(繁体字中国語)。

ロケールコードのマッチング

Adapty がクライアントサイド SDK からロケールコードを受け取り、対応するペイウォールのローカライゼーションを検索する際、次の処理が行われます。

  1. 受信したロケール文字列を小文字に変換し、アンダースコア(_)をすべてハイフン(-)に置き換えます
  2. 完全に一致するロケールコードのローカライゼーションを検索します
  3. 一致するものが見つからない場合、最初のハイフンより前の部分文字列(例:pt-br の場合は pt)を取り出し、一致するローカライゼーションを検索します
  4. それでも一致するものが見つからない場合、デフォルトの en ローカライゼーションを返します このようにすることで、'pt_BR'を送信したiOSデバイス、pt-BRを送信したAndroidデバイス、pt-brを送信した別のデバイスが、すべて同じ結果を受け取ることができます。

ローカライズについて検討しているなら、すでにプロジェクト内のローカライズ済み文字列ファイルを扱っているかと思います。その場合、各ローカライズファイルに Adapty のロケールコードをキーと値のペアとして記載することをおすすめします。そして SDK を呼び出す際に、そのキーの値を取り出して渡します。

// 1. Modify your app_en.arb, app_es.arb, app_pt_br.arb files

/*
app_en.arb
*/
"adapty_paywalls_locale": "en",

/*
app_es.arb
*/
"adapty_paywalls_locale": "es",

/*
app_pt_br.arb
*/
"adapty_paywalls_locale": "pt-br",

// 2. Extract and use the locale code
final locale = AppLocalizations.of(context)!.adapty_paywalls_locale;
// pass locale code to AdaptyUI.getViewConfiguration or Adapty.getPaywall method

この方法により、アプリの各ユーザーに対してどのローカライゼーションが取得されるかを完全にコントロールできます。

ローカリゼーションの別の実装方法

ロケールコードをすべてのローカリゼーションに明示的に定義しなくても、同様の(ただし完全に同じではない)結果を得ることができます。その場合、プラットフォームが提供する別のオブジェクトからロケールコードを取得する方法が考えられます。例えば次のようにします。

final locale = Localizations.localeOf(context).languageCode;
// pass locale code to AdaptyUI.getViewConfiguration or Adapty.getPaywall method

ただし、この方法はいくつかの理由からお勧めしません。

  1. iOSでは、優先言語と現在のロケールは同一ではありません。ローカライズが正しく選択されるようにするには、ローカライズされた文字列ファイルを使用する推奨のアプローチを利用してAppleのロジックにそのまま任せるか、独自に再実装する必要があります。
  2. Adaptyのサーバーが実際に何を受け取るかを予測するのは困難です。たとえばiOSでは、デバイスから ar_OM@numbers='latn' のようなロケールを取得してサーバーに送信することがあります。この場合、期待していた ar-om ローカライズではなく、ar が返されることになり、予期しない動作となる可能性があります。 万が一このアプローチを採用する場合は、関連するすべてのユースケースを網羅していることを確認してください。