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

これが重要な理由

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

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

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

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

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

SDK v4 では、フローとオンボーディングのロケールコードのマッチング方法が異なります。フローはデバイス上の SDK によってローカライズされ、オンボーディングは Adapty サーバーによってローカライズされます。

フローとペイウォールビルダーのペイウォール

ペイウォールビルダーで作成されたペイウォールは、SDK v4 ではフローとして配信されるため、以下のルールは両方に適用されます。

マッチングは完全一致です。SDK は渡されたコードをフローのローカライゼーションコードと1文字ずつ比較します。大文字・小文字の変換は行わず、アンダースコア(_)とハイフン(-)の置き換えも行わず、言語サブタグへのフォールバックもありません。pt-br のローカライゼーションを持つフローには、pt-br のみがマッチします。pt-BRpt_BRpt-PT はいずれも一致しません。

コードがどのローカライゼーションとも一致しない場合、フローはそのデフォルトロケールでサイレントにレンダリングされます。SDKはエラーを返さず、警告もログに記録しません。

コードが一致する場合、Adaptyはローカライゼーションをデフォルトのものとマージします。一致したローカライゼーションで定義されていない文字列やアセットは、デフォルトのローカライゼーションから補完されます。

ロケールコードを省略することは、フローのデフォルトのローカライゼーションを要求することとは異なります。SDKは固定の en で代替します。デフォルトロケールが de のフローに en のローカライゼーションが存在する場合は en で表示され、存在しない場合のみ de にフォールバックします。

Warning

ロケールコードは、ダッシュボードで設定されている通りに正確に渡してください。小文字のサブタグをハイフンで区切った形式です。デバイスのロケール識別子をそのまま渡さないでください。react-native-localizegetLocales()[0].languageTagpt-BR を返しますが、これはデフォルトのローカライズにフォールバックします。アプリ内で値を変換してから渡してください。

オンボーディング

オンボーディングはサーバー側でローカライズされており、サーバーのルールは他のフォーマットにも対応しています。getOnboardinglocale を渡すと、以下の順序で処理されます:

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

この方法により、pt_BRpt-BRpt-br はすべて同じオンボーディングのローカライゼーションに解決されます。

ローカライズの実装

SDK v4 では、フローを取得する際にロケールコードを渡す必要はありません。getFlow はすべてのローカライズを含むフローを返し、フローのビューが構築される際に Adapty が適切なものを適用します。

  • ビルダーで作成したフロー: SDK はデバイスのロケールを読み取らないため、アプリ側でロケールを解決し、createFlowViewlocale パラメーター、またはエンベッドされた AdaptyFlowView コンポーネントの params プロパティとして渡してください。これは省略可能です — 省略するとフローは en でレンダリングされます。ただし、フローに en のローカライズがない場合はデフォルトロケールでレンダリングされます。

    import { createFlowView } from 'react-native-adapty';
    
    const view = await createFlowView(flow, { locale: 'es' });

view.locale は、ビューが実際に構築されたローカライゼーションを報告します。リクエストしたロケールが存在する場合はそのロケール、存在しない場合はフローのデフォルトが使用されます。locale パラメーターと view.locale の両方に React Native SDK 4.0.2 以降が必要です。それより前のバージョンでは view.localeundefined になります。

埋め込み AdaptyFlowView コンポーネントは独自のビューを作成するため、コードから locale を読み取る対象がありません。代わりに、onAppeared ハンドラーが受け取るオブジェクトからローカライゼーションを取得してください。

  <AdaptyFlowView
    flow={flow}
    params={{ locale: 'es' }}
    onAppeared={(view) => setScreenLocale(view.locale)}
  />

onAppeared 引数には React Native SDK 4.0.3 以降が必要です。

  • カスタム(リモートコンフィグ)ペイウォール: 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

Adapty はこれらの lang コードを Adaptyのロケールコード標準 で説明されているフォーマットで保存します。SDK はリモートコンフィグをロケールに対して自動的に照合しないため、どのエントリを適用するかはアプリ側で決定します。

これが重要な理由

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

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

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

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

ロケールコードの照合

Adapty がクライアントサイド SDK からロケールコードを受け取り、ペイウォールに対応するローカライズを探す際、以下の処理が行われます。

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

'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にフォールバックします — これは、そのユーザーに対してデフォルトにしたい言語ではない可能性があります。 万が一このアプローチを採用する場合は、関連するすべてのユースケースに対応していることを確認してください。