Capacitor SDKでローカライゼーションとロケールコードを使用する

これが重要な理由

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

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

Adaptyのロケールコード標準

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

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

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

  1. ロケール文字列が小文字に変換され、アンダースコア(_)がすべてハイフン(-)に置き換えられます
  2. Adapty はロケールコードが完全に一致するローカライズを検索します
  3. 一致するものが見つからない場合、最初のハイフンより前の部分文字列(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({ placementId: 'placement_id' });
const config = flow.remoteConfigs?.find((c) => c.lang === 'en') ?? flow.remoteConfigs?.[0];
// read your values from config?.data

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

これが重要な理由

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

ロケールコードはプラットフォームによって異なり複雑なため、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);
  };
};

That way you can ensure you’re in full control of what localization will be retrieved for every user of your app.

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

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


const getLocaleCode = () => {
  if (Capacitor.getPlatform() === 'ios') {
    return navigator.language || 'en';
  } else {
    return navigator.language || 'en';
  }
};

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

この方法はいくつかの理由からお勧めしません:

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