Миграция Adapty React Native SDK на версию 3.3
Adapty SDK 3.3.1 — это мажорный релиз, который принёс ряд улучшений, требующих выполнения шагов миграции.
- Обновите Adapty SDK до версии 3.3.x.
- Обновите модели.
- Удалите метод
getProductsIntroductoryOfferEligibility. - Обновите процесс совершения покупки.
- Обновите отображение пейволов Paywall Builder.
- Пересмотрите реализацию таймеров, определяемых разработчиком.
- Обновите обработку событий покупки в Paywall Builder.
- Обновите обработку событий кастомных действий в Paywall Builder.
- Измените коллбэк
onProductSelected. - Удалите параметры сторонних интеграций из метода
updateProfile. - Обновите конфигурации интеграций для Adjust, AirBridge, Amplitude, AppMetrica, Appsflyer, Branch, Facebook Ads, Firebase и Google Analytics, Mixpanel, OneSignal и Pushwoosh.
- Обновите реализацию режима Observer.
Обновление Adapty React Native SDK до версии 3.3.x
До версии 3.3.1 SDK react-native-adapty являлся основным и обязательным SDK для работы Adapty в вашем приложении. SDK @adapty/react-native-ui был опциональным и требовался только при использовании Adapty Paywall Builder.
Начиная с версии 3.3.1, SDK @adapty/react-native-ui признан устаревшим, а его функциональность объединена с SDK react-native-adapty. Чтобы перейти на версию 3.3.1, выполните следующие шаги:
- Обновите пакет
react-native-adaptyдо версии 3.3.1. - Удалите пакет
@adapty/react-native-uiиз зависимостей проекта. - Синхронизируйте зависимости проекта, чтобы применить изменения.
Изменения в моделях
Новые модели
-
export interface AdaptySubscriptionOffer { readonly identifier: AdaptySubscriptionOfferId; phases: AdaptyDiscountPhase[]; android?: { offerTags?: string[]; }; } -
export type AdaptySubscriptionOfferId = | { id?: string; type: 'introductory'; } | { id: string; type: 'promotional' | 'win_back'; };
Изменённые модели
-
-
Свойство
subscriptionDetailsпереименовано вsubscription.
- subscriptionDetails?: AdaptySubscriptionDetails; + subscription?: AdaptySubscriptionDetails; -
-
-
Свойство
promotionalOfferудалено. Теперь promotional offer передаётся через свойствоofferтолько если он доступен. В этом случаеoffer?.identifier?.typeбудет иметь значение'promotional'. -
Свойство
introductoryOfferEligibilityудалено (офферы возвращаются только если пользователь имеет право на их получение). -
Свойство
offerIdудалено. ID оффера теперь хранится вAdaptySubscriptionOffer.identifier. -
Свойство
offerTagsперемещено вAdaptySubscriptionOffer.android.
- introductoryOffers?: AdaptyDiscountPhase[]; + offer?: AdaptySubscriptionOffer; ios?: { - promotionalOffer?: AdaptyDiscountPhase; subscriptionGroupIdentifier?: string; }; android?: { - offerId?: string; basePlanId: string; - introductoryOfferEligibility: OfferEligibility; - offerTags?: string[]; renewalType?: 'prepaid' | 'autorenewable'; }; } -
-
-
Поле
identifierудалено из моделиAdaptyDiscountPhase. Идентификатор оффера теперь хранится вAdaptySubscriptionOffer.identifier.
- ios?: { - readonly identifier?: string; - }; -
Удалённые модели
AttributionSource:- Вместо него теперь используется строка там, где ранее применялся
AttributionSource.
- Вместо него теперь используется строка там, где ранее применялся
OfferEligibility:- Эта модель удалена, так как больше не нужна. Теперь оффер возвращается только если пользователь имеет право на его получение.
Удаление метода getProductsIntroductoryOfferEligibility
До Adapty SDK 3.3.1 объекты продуктов всегда включали офферы, даже если пользователь не имел права на их получение. Это требовало ручной проверки права на получение оффера перед его использованием.
Начиная с версии 3.3.1, объект продукта включает офферы только если пользователь имеет на них право. Это упрощает процесс: если оффер присутствует, можно считать, что пользователь имеет право на его получение.
Обновление процесса совершения покупки
В более ранних версиях отменённые и отложенные покупки считались ошибками и возвращали коды 2: 'paymentCancelled' и 25: 'pendingPurchase' соответственно.
Начиная с версии 3.3.1, отменённые и отложенные покупки считаются успешными результатами и должны обрабатываться соответствующим образом:
try {
const purchaseResult = await adapty.makePurchase(product);
switch (purchaseResult.type) {
case 'success':
const isSubscribed = purchaseResult.profile?.accessLevels['YOUR_ACCESS_LEVEL']?.isActive;
if (isSubscribed) {
// Grant access to the paid features
}
break;
case 'user_cancelled':
// Handle the case where the user canceled the purchase
break;
case 'pending':
// Handle deferred purchases (e.g., the user will pay offline with cash)
break;
}
} catch (error) {
// Handle the error
}
Обновление отображения пейволов Paywall Builder
Актуальные примеры смотрите в документации Отображение новых пейволов Paywall Builder в React Native.
- import { createPaywallView } from '@adapty/react-native-ui';
+ import { createPaywallView } from 'react-native-adapty/dist/ui';
const view = await createPaywallView(paywall);
view.registerEventHandlers(); // handle close press, etc
try {
await view.present();
} catch (error) {
// handle the error
}
Обновление реализации таймеров, определяемых разработчиком
Переименуйте параметр timerInfo в customTimers:
- let timerInfo = { 'CUSTOM_TIMER_NY': new Date(2025, 0, 1) }
+ let customTimers = { 'CUSTOM_TIMER_NY': new Date(2025, 0, 1) }
//and then you can pass it to createPaywallView as follows:
- view = await createPaywallView(paywall, { timerInfo })
+ view = await createPaywallView(paywall, { customTimers })
Обновление событий покупки в Paywall Builder
Ранее:
- Отменённые покупки вызывали коллбэк
onPurchaseCancelled. - Отложенные покупки возвращали код ошибки
25: 'pendingPurchase'.
Теперь:
- Оба случая обрабатываются коллбэком
onPurchaseCompleted.
Шаги миграции:
- Удалите коллбэк
onPurchaseCancelled. - Удалите обработку кода ошибки
25: 'pendingPurchase'. - Обновите коллбэк
onPurchaseCompleted:
const view = await createPaywallView(paywall);
const unsubscribe = view.registerEventHandlers({
// ... other optional callbacks
onPurchaseCompleted(purchaseResult, product) {
switch (purchaseResult.type) {
case 'success':
const isSubscribed = purchaseResult.profile?.accessLevels['YOUR_ACCESS_LEVEL']?.isActive;
if (isSubscribed) {
// Grant access to the paid features
}
break;
case 'user_cancelled':
// Handle the case where the user canceled the purchase
break;
case 'pending':
// Handle deferred purchases (e.g., the user will pay offline with cash)
break;
}
return purchaseResult.type !== 'user_cancelled';
},
});
Обновление событий кастомных действий в Paywall Builder
Удалённые коллбэки:
onActiononCustomEvent
Добавленный коллбэк:
- Новый коллбэк
onCustomAction(actionId). Используйте его для кастомных действий.
Изменение коллбэка onProductSelected
Ранее onProductSelected принимал объект product. Теперь требуется productId в виде строки.
Удаление параметров сторонних интеграций из метода updateProfile
Идентификаторы сторонних интеграций теперь задаются с помощью метода setIntegrationIdentifier. Метод updateProfile больше не принимает их.
Обновление конфигурации SDK сторонних интеграций
Чтобы интеграции корректно работали с Adapty React Native SDK 3.3.1 и выше, обновите конфигурации SDK для следующих интеграций согласно разделам ниже.
Кроме того, если вы использовали AttributionSource для получения идентификатора атрибуции, измените код так, чтобы передавать нужный идентификатор в виде строки.
Adjust
Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе Конфигурация SDK для интеграции Adjust.
import { Adjust, AdjustConfig } from "react-native-adjust";
import { adapty } from "react-native-adapty";
var adjustConfig = new AdjustConfig(appToken, environment);
// Before submiting Adjust config...
adjustConfig.setAttributionCallbackListener(attribution => {
// Make sure Adapty SDK is activated at this point
// You may want to lock this thread awaiting of `activate`
adapty.updateAttribution(attribution, "adjust");
});
// ...
Adjust.create(adjustConfig);
+ Adjust.getAdid((adid) => {
+ if (adid)
+ adapty.setIntegrationIdentifier("adjust_device_id", adid);
+ });
AirBridge
Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе Конфигурация SDK для интеграции AirBridge.
import Airbridge from 'airbridge-react-native-sdk';
import { adapty } from 'react-native-adapty';
try {
const deviceId = await Airbridge.state.deviceUUID();
- await adapty.updateProfile({
- airbridgeDeviceId: deviceId,
- });
+ await adapty.setIntegrationIdentifier("airbridge_device_id", deviceId);
} catch (error) {
// handle `AdaptyError`
}
Amplitude
Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе Конфигурация SDK для интеграции Amplitude.
try {
- await adapty.updateProfile({
- amplitudeDeviceId: deviceId,
- amplitudeUserId: userId,
- });
+ await adapty.setIntegrationIdentifier("amplitude_device_id", deviceId);
+ await adapty.setIntegrationIdentifier("amplitude_user_id", userId);
} catch (error) {
// handle `AdaptyError`
}
AppMetrica
Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе Конфигурация SDK для интеграции AppMetrica.
import AppMetrica, { DEVICE_ID_KEY, StartupParams, StartupParamsReason } from '@appmetrica/react-native-analytics';
// ...
const startupParamsCallback = async (
params?: StartupParams,
reason?: StartupParamsReason
) => {
const deviceId = params?.deviceId
if (deviceId) {
try {
- await adapty.updateProfile({
- appmetricaProfileId: 'YOUR_ADAPTY_CUSTOMER_USER_ID',
- appmetricaDeviceId: deviceId,
- });
+ await adapty.setIntegrationIdentifier("appmetrica_profile_id", 'YOUR_ADAPTY_CUSTOMER_USER_ID');
+ await adapty.setIntegrationIdentifier("appmetrica_device_id", deviceId);
} catch (error) {
// handle `AdaptyError`
}
}
}
AppMetrica.requestStartupParams(startupParamsCallback, [DEVICE_ID_KEY])
AppsFlyer
Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе Конфигурация SDK для интеграции AppsFlyer.
import { adapty, AttributionSource } from 'react-native-adapty';
import appsFlyer from 'react-native-appsflyer';
appsFlyer.onInstallConversionData(installData => {
try {
- const networkUserId = appsFlyer.getAppsFlyerUID();
- adapty.updateAttribution(installData, AttributionSource.AppsFlyer, networkUserId);
+ const uid = appsFlyer.getAppsFlyerUID();
+ adapty.setIntegrationIdentifier("appsflyer_id", uid);
+ adapty.updateAttribution(installData, "appsflyer");
} catch (error) {
// handle the error
}
});
// ...
appsFlyer.initSdk(/*...*/);
Branch
Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе Конфигурация SDK для интеграции Branch.
import branch from 'react-native-branch';
branch.subscribe({
enComplete: ({
params,
}) => {
- adapty.updateAttribution(params, AttributionSource.Branch);
+ adapty.updateAttribution(params, "branch");
},
});
Facebook Ads
Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе Конфигурация SDK для интеграции Facebook Ads.
import { AppEventsLogger } from 'react-native-fbsdk-next';
try {
const anonymousId = await AppEventsLogger.getAnonymousID();
- await adapty.updateProfile({
- facebookAnonymousId: anonymousId,
- });
+ await adapty.setIntegrationIdentifier("facebook_anonymous_id", anonymousId);
} catch (error) {
// handle `AdaptyError`
}
Firebase и Google Analytics
Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе Конфигурация SDK для интеграции Firebase и Google Analytics.
import analytics from '@react-native-firebase/analytics';
try {
const appInstanceId = await analytics().getAppInstanceId();
- await adapty.updateProfile({
- firebaseAppInstanceId: appInstanceId,
- });
+ await adapty.setIntegrationIdentifier("firebase_app_instance_id", appInstanceId);
} catch (error) {
// handle `AdaptyError`
}
Mixpanel
Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе Конфигурация SDK для интеграции Mixpanel.
import { Mixpanel } from 'mixpanel-react-native';
// ...
try {
- await adapty.updateProfile({
- mixpanelUserId: mixpanelUserId,
- });
+ await adapty.setIntegrationIdentifier("mixpanel_user_id", mixpanelUserId);
} catch (error) {
// handle `AdaptyError`
}
OneSignal
Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе Конфигурация SDK для интеграции OneSignal.
Pushwoosh
Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе Конфигурация SDK для интеграции Pushwoosh.
import Pushwoosh from 'pushwoosh-react-native-plugin';
// ...
try {
- await adapty.updateProfile({
- pushwooshHWID: hwid,
- });
+ await adapty.setIntegrationIdentifier("pushwoosh_hwid", hwid);
} catch (error) {
// handle `AdaptyError`
}
Обновление реализации режима Observer
Обновите способ привязки пейволов к транзакциям. Раньше для назначения variationId использовался метод setVariationId. Теперь можно передавать variationId напрямую при регистрации транзакции с помощью нового метода reportTransaction. Итоговый пример кода смотрите в разделе Привязка пейволов к транзакциям покупки в режиме Observer.
Не забудьте зарегистрировать транзакцию с помощью метода reportTransaction. Если пропустить этот шаг, Adapty не распознает транзакцию, не предоставит уровни доступа, не включит её в аналитику и не отправит в интеграции. Этот шаг обязателен!
Обратите внимание, что порядок параметров метода reportTransaction отличается от порядка параметров метода setVariationId.
const variationId = paywall.variationId;
try {
- await adapty.setVariationId(variationId, transactionId);
+ await adapty.reportTransaction(transactionId, variationId);
} catch (error) {
// handle the `AdaptyError`
}