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

これが重要な理由

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

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

Adaptyのロケールコード標準

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

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

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

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

これにより、'pt_BR'pt-BRpt-br はすべて同じローカライゼーションに解決されます。

ローカライゼーションの実装

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

  • ビルダーで作成したフロー: SDKはデバイスのロケールを読み取らないため、アプリ側でロケールを解決し、createFlowViewlocaleオプションとして渡してください。これは省略可能です。省略した場合、フローはenでレンダリングされます。ただし、フローにenのローカライズがない場合はデフォルトロケールが使用されます。フローが持っていないローカライズをリクエストした場合、エラーなしにフローのデフォルトにフォールバックし、選択したローカライズで不足している文字列はデフォルトのものが使用されます。
  import { createFlowView } from '@adapty/capacitor';

  const view = await createFlowView(flow, { locale: 'es' });

view.locale はビューのビルドに使用されたローカライゼーションを返します。locale オプションと view.locale はどちらも Capacitor SDK 4.0.1-beta.1 以降が必要で、それより古いバージョンでは view.localeundefined になります。

  • カスタム(リモートコンフィグ)ペイウォール: 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. それでも一致するものが見つからない場合、ペイウォールのデフォルトロケールのコンテンツを返します

このようにすることで、'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 が返されることになり、意図しない結果になる可能性があります。 そのアプローチを使用する場合は、関連するすべてのユースケースを確実にカバーしてください。