将 Adapty React Native SDK 迁移至 v. 3.3
Adapty SDK 3.3.1 是一个主要版本,带来了一些改进,可能需要您执行一些迁移步骤。
- 升级至 Adapty SDK v3.3.x。
- 更新模型。
- 移除
getProductsIntroductoryOfferEligibility方法。 - 更新购买流程。
- 更新付费墙编辑工具付费墙的展示方式。
- 修改开发者自定义计时器的实现方式。
- 更新付费墙编辑工具购买事件的处理方式。
- 更新付费墙编辑工具自定义操作事件的处理方式。
- 修改
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 版本之前,react-native-adapty SDK 是 Adapty 在您的应用中正常运行所必需的核心 SDK。@adapty/react-native-ui SDK 是可选的,仅在您使用 Adapty 付费墙编辑工具时才需要。
从 3.3.1 版本起,@adapty/react-native-ui SDK 已被弃用,其功能已合并至 react-native-adapty SDK。要升级至 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已被移除。现在促销活动仅在可用时通过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
}
更新付费墙编辑工具付费墙的展示方式
有关更新后的示例,请参阅在 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 })
修改付费墙编辑工具购买事件
之前的行为:
- 取消购买会触发
onPurchaseCancelled回调。 - 待处理购买返回错误码
25: 'pendingPurchase'。
现在:
- 两者均由
onPurchaseCompleted回调处理。
迁移步骤:
- 移除
onPurchaseCancelled回调。 - 移除错误码
25: 'pendingPurchase'的处理逻辑。 - 更新
onPurchaseCompleted回调:
import {createPaywallView} from 'react-native-adapty/dist/ui';
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';
},
});
修改付费墙编辑工具自定义操作事件
已移除的回调:
onActiononCustomEvent
新增的回调:
- 新增
onCustomAction(actionId)回调,用于处理自定义操作。
修改 onProductSelected 回调
之前,onProductSelected 需要传入 product 对象。现在改为接受字符串类型的 productId。
从 updateProfile 方法中移除第三方集成参数
第三方集成标识符现在通过 setIntegrationIdentifier 方法进行设置。updateProfile 方法不再接受这些参数。
更新第三方集成 SDK 配置
为确保集成能够与 Adapty React Native SDK 3.3.1 及更高版本正常工作,请按照以下各节的说明更新您的 SDK 配置。
此外,如果您之前使用 AttributionSource 获取归因标识符,请将代码修改为以字符串形式提供所需标识符。
Adjust
按如下方式更新您的移动应用代码。完整代码示例请参阅 Adjust 集成的 SDK 配置。
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
按如下方式更新您的移动应用代码。完整代码示例请参阅 AirBridge 集成的 SDK 配置。
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
按如下方式更新您的移动应用代码。完整代码示例请参阅 Amplitude 集成的 SDK 配置。
import { adapty } from 'react-native-adapty';
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
按如下方式更新您的移动应用代码。完整代码示例请参阅 AppMetrica 集成的 SDK 配置。
import { adapty } from 'react-native-adapty';
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
按如下方式更新您的移动应用代码。完整代码示例请参阅 AppsFlyer 集成的 SDK 配置。
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
按如下方式更新您的移动应用代码。完整代码示例请参阅 Branch 集成的 SDK 配置。
import { adapty, AttributionSource } from 'react-native-adapty';
import branch from 'react-native-branch';
branch.subscribe({
enComplete: ({
params,
}) => {
- adapty.updateAttribution(params, AttributionSource.Branch);
+ adapty.updateAttribution(params, "branch");
},
});
Facebook Ads
按如下方式更新您的移动应用代码。完整代码示例请参阅 Facebook Ads 集成的 SDK 配置。
import { adapty } from 'react-native-adapty';
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
按如下方式更新您的移动应用代码。完整代码示例请参阅 Firebase 和 Google Analytics 集成的 SDK 配置。
import analytics from '@react-native-firebase/analytics';
import { adapty } from 'react-native-adapty';
try {
const appInstanceId = await analytics().getAppInstanceId();
- await adapty.updateProfile({
- firebaseAppInstanceId: appInstanceId,
- });
+ await adapty.setIntegrationIdentifier("firebase_app_instance_id", appInstanceId);
} catch (error) {
// handle `AdaptyError`
}
Mixpanel
按如下方式更新您的移动应用代码。完整代码示例请参阅 Mixpanel 集成的 SDK 配置。
import { adapty } from 'react-native-adapty';
import { Mixpanel } from 'mixpanel-react-native';
// ...
try {
- await adapty.updateProfile({
- mixpanelUserId: mixpanelUserId,
- });
+ await adapty.setIntegrationIdentifier("mixpanel_user_id", mixpanelUserId);
} catch (error) {
// handle `AdaptyError`
}
OneSignal
按如下方式更新您的移动应用代码。完整代码示例请参阅 OneSignal 集成的 SDK 配置。
Pushwoosh
按如下方式更新您的移动应用代码。完整代码示例请参阅 Pushwoosh 集成的 SDK 配置。
import { adapty } from 'react-native-adapty';
import Pushwoosh from 'pushwoosh-react-native-plugin';
// ...
try {
- await adapty.updateProfile({
- pushwooshHWID: hwid,
- });
+ await adapty.setIntegrationIdentifier("pushwoosh_hwid", hwid);
} catch (error) {
// handle `AdaptyError`
}
更新 Observer 模式的实现方式
更新付费墙与交易的关联方式。之前,您使用 setVariationId 方法来分配 variationId。现在,您可以在使用新的 reportTransaction 方法记录交易时直接包含 variationId。请查看在 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`
}