Показ пейвола с таргетингом Apple Ads при первом запуске в Capacitor SDK

Эта статья относится к iOS-сборке вашего приложения. Атрибуция Apple Ads доступна только на iOS.

Атрибуция Apple Ads (AA) поступает асинхронно после вызова adapty.activate(). При первом запуске она обычно ещё не получена, поэтому getFlow разрешается по аудитории по умолчанию, и пользователи Apple Ads не видят пейвол, настроенный под AA-сегмент. Вместо того чтобы откладывать показ пейвола до получения атрибуции, покажите его сразу, а затем обновите после применения атрибуции AA — тогда пользователи Apple Ads получат целевой вариант, а остальные не будут ждать. AdaptyProfile.appliedExternalAttributionProviders сообщает, когда атрибуция AA применена.

Important

appliedExternalAttributionProviders отображает только данные Apple Ads. Атрибуция от других провайдеров видна в профилях пользователей и доступна в фильтрах сегментов, но пока не здесь.

Прежде чем начать

Вам понадобится:

  • Adapty Capacitor SDK 4.1 или новее. В версиях 3.17.1–4.0 свойство профиля называется appliedAttributionSources, а в 3.17.1 пейволы получаются через getPaywall вместо getFlow.
  • Apple Ads, настроенный для приложения в Adapty. См. Apple Ads.

Как это работает

После вызова adapty.activate() SDK в фоновом режиме запрашивает атрибуцию Apple Ads у Apple и передаёт результат на бэкенд Adapty. Когда AA становится активным источником атрибуции для профиля, SDK доставляет обновлённый AdaptyProfile в ваш слушатель onLatestProfileLoad, где в массиве appliedExternalAttributionProviders появится 'apple_search_ads'.

Это позволяет загружать пейвол в два шага:

  1. Вызовите getFlow сразу. Поскольку атрибуция ещё не применена, Adapty разрешает запрос для аудитории по умолчанию, и пользователь сразу видит пейвол.
  2. Когда появляется 'apple_search_ads', вызовите getFlow снова. Теперь Adapty разрешает запрос для аудитории Apple Ads и возвращает целевой пейвол, который заменяет первый.

appliedExternalAttributionProviders может быть пустым или отсутствовать. Это означает одно из следующего:

  • Атрибуция Apple Ads для этого профиля ещё не обработана.
  • Атрибуция не поступала вовсе.
  • Атрибуция поступила от другого провайдера, который этот массив не отражает.

Во всех трёх случаях шаг 1 безопасен — Adapty разрешает запрос относительно аудитории, которая соответствует текущему состоянию профиля, как правило это аудитория по умолчанию. Шаг 2 выполняется только после того, как появится 'apple_search_ads'.

Important

При каждом последующем запуске кэшированный профиль уже содержит 'apple_search_ads' в appliedExternalAttributionProviders, поэтому первый же getFlow возвращает пейвол, сегментированный по Apple Ads, — никакого повторного запроса или видимых изменений не происходит. Двухшаговый флоу важен только при первом запуске, пока атрибуция ещё не получена.

Реализация

Покажите пейвол сразу, а затем слушайте событие 'apple_search_ads' и обновляйте пейвол при его получении.

  1. Активируйте SDK. См. Установка и настройка Capacitor SDK.
  2. Загрузите и покажите пейвол с помощью getFlow как обычно — не блокируйте на атрибуции.
  3. Подпишитесь на обновления профиля через adapty.addListener('onLatestProfileLoad', …) и отслеживайте появление 'apple_search_ads'. Когда оно появится, снова запросите пейвол и покажите обновлённый. Если вы ещё не настроили слушатель, см. Отслеживание обновлений подписки:
const listener = await adapty.addListener('onLatestProfileLoad', async ({ profile }) => {
  if (!profile.appliedExternalAttributionProviders?.includes('apple_search_ads')) return;
  const targeted = await adapty.getFlow({ placementId });
  // present the targeted flow in place of the first one
});

// Call listener.remove() after the upgrade, or after a timeout (see below).
  1. Прекращайте слушать по таймауту. Большинство пользователей никогда не получают атрибуцию Apple Ads, поэтому удаляйте слушатель через некоторое время, а не держите его открытым на протяжении всей сессии. Настройте резервный пейвол для плейсмента, чтобы пользователь всегда что-то видел в случае ошибки запроса.

Полный пример

onAppleAdsAttribution резолвится, когда атрибуция Apple Ads применена, или отклоняется по истечении timeoutMs. В примере ниже пейвол загружается сразу, а затем перезагружается, когда приходит атрибуция — пользователи Apple Ads видят целевой пейвол, а если атрибуция так и не пришла, остаётся первый пейвол:


const APPLE_ADS_PROVIDER = 'apple_search_ads';
const placementId = 'YOUR_PLACEMENT_ID';

function hasAppleAdsAttribution(profile: AdaptyProfile): boolean {
  return profile.appliedExternalAttributionProviders?.includes(APPLE_ADS_PROVIDER) ?? false;
}

/**
 * Resolves once Apple Ads attribution is applied to the profile.
 * Rejects with a timeout error if attribution never arrives within `timeoutMs`.
 * Call after `adapty.activate()`.
 */
export function onAppleAdsAttribution(timeoutMs: number): Promise<void> {
  return new Promise((resolve, reject) => {
    let timer: ReturnType<typeof setTimeout> | undefined;
    let handle: { remove: () => void } | undefined;

    const stop = () => {
      clearTimeout(timer);
      handle?.remove();
    };

    adapty
      .addListener('onLatestProfileLoad', ({ profile }) => {
        if (!hasAppleAdsAttribution(profile)) return;
        stop();
        resolve();
      })
      .then(listener => {
        handle = listener;
      });

    timer = setTimeout(() => {
      stop();
      reject(new Error(`Apple Ads attribution timed out after ${timeoutMs}ms`));
    }, timeoutMs);
  });
}

let flow = await adapty.getFlow({ placementId });

onAppleAdsAttribution(30_000)
  .then(() => adapty.getFlow({ placementId }))
  .then(updated => {
    flow = updated;
  })
  .catch(() => {
    console.log('Apple Ads attribution or loading failed');
  });

При первом запуске пользователь Apple Ads ненадолго видит пейвол по умолчанию, прежде чем он заменяется. Если вы показываете пейволы через Paywall Builder, решите, допустимо ли повторное отображение, или применяйте обновление до того, как пейвол будет показан. Настройте timeoutMs в зависимости от того, сколько вы готовы ждать — атрибуция, если она придёт, обычно поступает в течение нескольких секунд после запуска.

Если ваше приложение уже слушает onLatestProfileLoad для других целей (например, проверки статуса подписки), менять ничего не нужно. adapty.addListener поддерживает несколько независимых слушателей, поэтому этот добавляется самостоятельно, не затрагивая остальные.