React Native SDKでローカライズとロケールコードを使用する

これが重要な理由

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

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

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

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

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

Adapty がユーザーのロケールに一致するローカライズを検索する際、以下の処理が行われます:

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

このようにして、'pt_BR'pt-BRpt-br はすべて同じローカライズに解決されます。

ローカライズの実装

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

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

const flow = await adapty.getFlow('placement_id');
const config = flow.remoteConfigs?.find((c) => c.lang === 'en') ?? flow.remoteConfigs?.[0];
// read your values from config?.data

上記のロケールコードマッチングルールは、各リモートコンフィグに保存された lang コードを 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 localization files (e.g., using react-i18next)

/*
en.json
*/
{
  "adapty_paywalls_locale": "en"
}

/*
es.json
*/
{
  "adapty_paywalls_locale": "es"
}

/*
pt-BR.json
*/
{
  "adapty_paywalls_locale": "pt-br"
}

// 2. Extract and use the locale code

const MyComponent = () => {
  const { t } = useTranslation();
  
  const fetchPaywall = async () => {
    const locale = t('adapty_paywalls_locale');
    // pass locale code to adapty.getPaywall or adapty.getPaywallForDefaultAudience method
    const paywall = await adapty.getPaywallForDefaultAudience('placement_id', locale);
  };
};

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

ローカライゼーションの実装:別の方法

すべてのローカライゼーションにロケールコードを明示的に定義しなくても、同様の(ただし完全に同一ではない)結果を得ることができます。その方法は、たとえば react-native-localize を使って、デバイスからロケールコードを取得するというものです。


const fetchPaywall = async () => {
  // getLocales() はユーザーの優先ロケールをBCP-47形式(例: 'en-US', 'pt-BR')で返します
  const locale = RNLocalize.getLocales()[0].languageTag;
  // ロケールコードを adapty.getPaywall または adapty.getPaywallForDefaultAudience メソッドに渡します
  const paywall = await adapty.getPaywallForDefaultAudience('placement_id', locale);
};

このアプローチはいくつかの理由からお勧めしません。

  1. iOSでは、優先言語と現在の地域ロケールは必ずしも一致しません。ローカライゼーションが正しく選択されるようにするには、推奨されているローカライズされた文字列ファイルを使用するアプローチで動作するAppleの解決ロジックに任せるか、自分でその仕組みを再現する必要があります。
  2. デバイスのロケールが、Adaptyで設定したどのローカライゼーションとも一致しない場合があります。その場合、SDKは最初のサブタグでマッチングを試み、それでも見つからない場合は最終的にenにフォールバックします — これは、そのユーザーに対してデフォルトにしたい言語ではない可能性があります。 万が一このアプローチを採用する場合は、関連するすべてのユースケースに対応していることを確認してください。