将 Adapty Kotlin Multiplatform SDK 迁移至 v4.1
Adapty Kotlin Multiplatform SDK 4.1 是 4.x 系列的第一个稳定版本——4.0 仅作为 Beta 版发布,因此如果你当前使用的是 3.x 版本,请直接迁移至 4.1。本指南涵盖完整迁移内容:4.0 中引入的流程变更,以及 4.1 在此基础上的进一步更新。
4.x 版本引入了流程功能,并相应地重命名了付费墙相关 API。新 API 同时兼容流程与付费墙编辑工具以及旧版付费墙编辑工具——Adapty 看板端无需任何配置变更。此外,4.1 版本将 Adapty Attribution 改为按需启用,重命名了外部归因 API 和产品订阅类型,并新增了 App Store 应用内购买推广功能。
从 4.0 beta 升级过来?更新版本号后,只需关注以下五个章节:Adapty 归因默认禁用、已重命名的外部归因 API、AdaptyPaywallProductSubscription → AdaptyProductSubscription、App Store 应用内购买推广,以及选择特定布局。hasViewConfiguration 也已回归到流程模型。
快速参考
| v3 | v4.1 |
|---|---|
| Adapty Attribution 默认自动启用 | 默认禁用——通过 .withAdaptyAttributionEnabled(true) 选择启用 |
Adapty.getPaywall(placementId, locale) | Adapty.getFlow(placementId) |
Adapty.getPaywallForDefaultAudience(placementId, locale) | Adapty.getFlowForDefaultAudience(placementId) |
Adapty.getPaywallProducts(paywall) | Adapty.getPaywallProducts(flow) |
Adapty.logShowPaywall(paywall) | Adapty.logShowFlow(flow) |
AdaptyPaywall | AdaptyFlow |
AdaptyUI.createPaywallView(paywall, ...) | AdaptyUI.createFlowView(flow, ...) |
AdaptyUI.createNativePaywallView(...) → AdaptyNativePaywallView | AdaptyUI.createNativeFlowView(...) → AdaptyNativeFlowView |
AdaptyUIPaywallView | AdaptyUIFlowView |
AdaptyUI.presentPaywallView(view) / dismissPaywallView(view) | AdaptyUI.presentFlowView(view) / dismissFlowView(view) |
AdaptyUI.setPaywallsEventsObserver(observer) | AdaptyUI.setFlowsEventsObserver(observer) |
AdaptyUI.registerPaywallEventsListener / unregisterPaywallEventsListener | AdaptyUI.registerFlowEventsListener / unregisterFlowEventsListener |
AdaptyUIPaywallsEventsObserver | AdaptyUIFlowsEventsObserver |
AdaptyUIPaywallPlatformView(paywall, ...) | AdaptyUIFlowPlatformView(flow, ...) |
paywallViewDidPerformAction、paywallViewDidAppear 及其他 paywallView... 回调 | flowViewDidPerformAction、flowViewDidAppear 及其他 flowView... 回调 |
paywallViewDidFailRendering | flowViewDidReceiveError |
Adapty.updateAttribution(attribution, source),source 为 String 类型 | Adapty.updateExternalAttribution(attribution, provider),provider 为 AdaptyExternalAttributionProvider 类型 |
provider 以字符串形式传入,例如 "adjust" | 使用 AdaptyExternalAttributionProvider,例如 AdaptyExternalAttributionProvider.ADJUST |
AdaptyProfile.appliedAttributionSources: List<String> | AdaptyProfile.appliedExternalAttributionProviders: List<AdaptyExternalAttributionProvider> |
AdaptyPaywallProductSubscription | AdaptyProductSubscription |
| 促销应用内购买自动完成,无法拦截 | OnPromotedPurchaseListener 和 Adapty.makePromotedPurchase(product) 将完成控制权交还给应用 |
AdaptyPaywallProduct 保持原名——产品仍属于流程,getPaywallProducts 也保持原名,现在接受 AdaptyFlow 参数。getFlow 和 getFlowForDefaultAudience 方法不再接受 locale 参数——请改为传给 createFlowView。购买与用户画像相关的 API(makePurchase、restorePurchases、getProfile、identify、updateProfile)以及 setFallback 保持相同签名,但备用付费墙文件本身需要重新下载——详见备用文件。用户引导方法仍可使用,但已被弃用——详见用户引导 API 弃用说明。部分默认行为有所变更——详见默认行为变更。
安装
更新版本号并同步项目:
[versions]
adapty-kmp = "<the latest SDK version>"
[libraries]
adapty-kmp = { module = "io.adapty:adapty-kmp", version.ref = "adapty-kmp" }
adapty-kmp-ui = { module = "io.adapty:adapty-kmp-ui", version.ref = "adapty-kmp" }
adapty-kmp-ui 模块仅在你通过 Compose Multiplatform 层(view.present())渲染流程和付费墙时才需要。完整配置请参阅安装 Adapty SDK。
底层原生 Adapty SDK 已在两个平台上升级至 4.x 版本,并自动完成依赖解析——无需修改构建配置。iOS 部署目标保持 15.0,本次发布不作更改。
⚠️ Adapty 归因功能默认禁用
如果你使用 Adapty 归因 并升级到 SDK 4.1 但未主动开启,它将静默失效——安装事件将停止记录,且不会有任何警告提示。
在早期版本中,SDK 会自动为 Adapty 归因 注册安装事件。从 SDK 4.1 版本起,该功能默认关闭:SDK 不再注册安装事件,通过 setOnInstallationDetailsListener 设置的监听器不会触发,getCurrentInstallationStatus 返回 AdaptyInstallationStatus.Determined.NotAvailable。
如果您使用 Adapty 归因功能,请在激活 SDK 时启用它:
val config = AdaptyConfig
.Builder("PUBLIC_SDK_KEY")
+ .withAdaptyAttributionEnabled(true)
.build()
Adapty.activate(configuration = config)
如果你不使用 Adapty Attribution,则无需做任何更改。
获取流程
getPaywall → getFlow
返回类型从 AdaptyPaywall 变为 AdaptyFlow,locale 参数从获取调用移至 createFlowView;对于自定义付费墙,所有语言版本均在 flow.remoteConfigs 中返回:
- Adapty.getPaywall("YOUR_PLACEMENT_ID", locale = "en")
- .onSuccess { paywall ->
- // use the paywall
+ Adapty.getFlow("YOUR_PLACEMENT_ID")
+ .onSuccess { flow ->
+ AdaptyUI.createFlowView(flow = flow, locale = "en")
}
.onError { error ->
// handle the error
}
locale 在 createFlowView 中仍是可选参数:省略时,视图将以 en 渲染,若流程没有 en 本地化,则使用流程的默认本地化。详见本地化与语言代码。
getPaywallForDefaultAudience 也以相同方式重命名:
- Adapty.getPaywallForDefaultAudience("YOUR_PLACEMENT_ID", locale = "en")
+ Adapty.getFlowForDefaultAudience("YOUR_PLACEMENT_ID")
getPaywallProducts(paywall) → getPaywallProducts(flow)
getPaywallProducts 保持原名,但现在接受 AdaptyFlow 参数:
- Adapty.getPaywallProducts(paywall)
+ Adapty.getPaywallProducts(flow)
.onSuccess { products ->
// use the products
}
备用文件
备用文件的格式在 SDK v4 中发生了变化。请从 Placements > Fallbacks 下载新文件,并将其打包到您的应用中。
数据模型
getFlow 返回 AdaptyFlow 而非 AdaptyPaywall,对象结构也发生了变化:
v3 AdaptyPaywall 属性 | v4 AdaptyFlow 属性 | 操作 |
|---|---|---|
remoteConfig: AdaptyRemoteConfig?(单一) | remoteConfigs: List<AdaptyRemoteConfig> | 一个流程可携带每种已配置语言对应的一份远程配置。读取与用户匹配的那一份:flow.remoteConfigs.firstOrNull { it.locale == "en" }。 |
| (新增) | paywalls: List<AdaptyFlowPaywall> | 每个条目代表流程中的一个付费墙变体,包含其自身的 name、variationId 和 productIdentifiers。Web 付费墙方法接受 AdaptyFlowPaywall 参数——参见 Web 付费墙方法。 |
productIdentifiers | 已迁移 | 产品标识符现在位于每个变体上:flow.paywalls[i].productIdentifiers。获取产品时,继续调用 getPaywallProducts(flow) 即可。 |
hasViewConfiguration | 保留 | 表示该流程是否包含可供 AdaptyUI 渲染的布局。此属性在 4.0 测试版中缺失,4.1 版本已恢复——如果你在测试版期间移除了相关检查,现在可以重新使用。false 表示该流程不含布局,请将其视为仅远程配置模式。你也可以调用 createFlowView 并处理错误(参见 显示流程)。 |
hasViewConfiguration 也在 AdaptyOnboarding 上,保持不变。
Web 付费墙方法
openWebPaywall 和 createWebPaywallUrl 保持原有名称,但 paywall 参数已替换为 flowPaywall 参数,接受 AdaptyFlowPaywall 类型——即 flow.paywalls 中的某个实例。你也可以继续传入 AdaptyPaywallProduct:
- Adapty.openWebPaywall(paywall = paywall)
+ flow.paywalls.firstOrNull()?.let { flowPaywall ->
+ Adapty.openWebPaywall(flowPaywall = flowPaywall)
+ }
跟踪流程查看次数
logShowPaywall → logShowFlow
logShowPaywall 已重命名为 logShowFlow,现在接受一个 AdaptyFlow。事件仍记录到相同的实验变体,因此现有的漏斗和 A/B 测试数据图表无需更改看板即可继续使用。
- Adapty.logShowPaywall(paywall)
+ Adapty.logShowFlow(flow)
与 v3 中一样,当展示由 Adapty 渲染的流程或付费墙时,无需手动调用此方法——Adapty 会自动追踪这些展示事件。
显示流程
createPaywallView → createFlowView
重命名工厂方法,并传入 AdaptyFlow。返回的视图类型从 AdaptyUIPaywallView 改名为 AdaptyUIFlowView,但其方法(present、dismiss)和可选参数(loadTimeout、preloadProducts、customTags、customTimers、customAssets、productPurchaseParams)保持不变。新增了一个可选参数:locale,用于替代之前传给 getPaywall 的 locale 参数——详见获取流程。
customTimers 仍然存在,但它只影响旧版付费墙编辑工具的付费墙。flow 的倒计时器按照 Flow & Paywall Builder 中设置的行为运行,因此 flow 会忽略你在此传入的任何内容。
- AdaptyUI.createPaywallView(paywall)
+ AdaptyUI.createFlowView(flow)
.onSuccess { view ->
view.present()
}
.onError { error ->
// handle the error
}
如果你不使用 Compose Multiplatform,原生工厂方法的重命名方式相同:
- AdaptyUI.createNativePaywallView(paywall)
+ AdaptyUI.createNativeFlowView(flow)
createFlowView 在流程未配置视图时返回 AdaptyResult.Error,因此你可以省去 v3 中的 hasViewConfiguration 检查,改为直接处理该错误:
- if (paywall.hasViewConfiguration) {
- AdaptyUI.createPaywallView(paywall)
- .onSuccess { view -> view.present() }
- }
+ AdaptyUI.createFlowView(flow)
+ .onSuccess { view -> view.present() }
+ .onError { error ->
+ // the flow has no view configured, or view creation failed
+ }
流程视图为一次性使用:调用 dismiss() 后,视图即被销毁,若需再次展示该流程,请重新调用 createFlowView。
处理事件
事件观察器从 AdaptyUIPaywallsEventsObserver 更名为 AdaptyUIFlowsEventsObserver,其回调方法的 paywallView 前缀改为 flowView。现有的处理器主体无需修改代码——只需重命名类型和重写方法即可:
- AdaptyUI.setPaywallsEventsObserver(object : AdaptyUIPaywallsEventsObserver {
- override fun paywallViewDidFinishPurchase(
- view: AdaptyUIPaywallView,
+ AdaptyUI.setFlowsEventsObserver(object : AdaptyUIFlowsEventsObserver {
+ override fun flowViewDidFinishPurchase(
+ view: AdaptyUIFlowView,
product: AdaptyPaywallProduct,
purchaseResult: AdaptyPurchaseResult
) {
// custom logic after purchase
}
})
一个回调也已重命名:paywallViewDidFailRendering 改为 flowViewDidReceiveError。它会在与之前相同的渲染错误时触发,同时还涵盖其他非购买类运行时错误:
- override fun paywallViewDidFailRendering(view: AdaptyUIPaywallView, error: AdaptyError) {}
+ override fun flowViewDidReceiveError(view: AdaptyUIFlowView, error: AdaptyError) {}
完整回调列表请参阅处理流程与付费墙事件。
Compose 平台视图
如果你使用 Compose Multiplatform 的 composable 嵌入视图,AdaptyUIPaywallPlatformView(paywall, ...) 已重命名为 AdaptyUIFlowPlatformView(flow, ...)。事件回调保留原有的 onDid... 命名,但 onDidFailRendering 更名为 onDidReceiveError:
- AdaptyUIPaywallPlatformView(
- paywall = paywall,
+ AdaptyUIFlowPlatformView(
+ flow = flow,
onDidFinishPurchase = { view, product, result -> /* ... */ },
)
与 v3 相同,此处传入的回调(以及通过 registerFlowEventsListener 注册的任何观察者)会在全局观察者之外额外执行,而非取而代之——你的回调只是观察某个事件,并不会替换全局默认行为。请留意已更改的默认行为:例如,全局默认行为不再在购买后关闭视图。
新 API
AdaptyUI.setObserverModeResolver(...)配合AdaptyUIObserverModeResolver—— 在 SDK 以观察者模式运行时,驱动从流程中发起的购买和恢复操作。此前该功能仅在 iOS 和 Android 原生 SDK 中可用。详见在观察者模式下展示流程。AdaptyUI.setSystemRequestsHandler(...)配合AdaptyUISystemRequestsHandler—— 用于处理流程中的系统请求(系统权限提示和应用评价请求)。目前流程尚未触发这些请求,无需注册处理器。- 新增可选回调
flowViewDidReceiveAnalyticEvent,用于上报流程中的分析事件,从用户打开每个页面时的页面浏览事件开始。详见追踪流程页面浏览。 AdaptyUI.openWebUrl(url, openIn)和AdaptyUI.requestAppReview()—— 这两个方法分别为默认的OpenUrlAction处理逻辑和默认的handleAppReviewRequest提供支持,因此 URL 跳转和应用评价提示均可开箱即用地在原生端处理。只有在覆盖默认行为时,才需要直接调用它们。AdaptyUIFlowView.locale—— 报告视图构建时所使用的本地化语言,便于了解用户实际看到的是哪种语言。AdaptyConfig.ServerCluster.CN—— 新增服务器集群选项,与DEFAULT和EU并列,用于将应用连接至 Adapty 中国服务器。
重命名的外部归因 API
从 SDK 版本 4.1 开始,用于传递外部归因提供商(Adjust、AppsFlyer、Branch、Tenjin、Apple Ads 或自定义提供商)数据的 API 已重命名,以与原生 SDK 保持一致,同时提供商参数也从字符串类型更改为枚举类型。由于没有提供废弃的别名,现有的调用代码在更新之前将无法通过编译。
updateAttribution → updateExternalAttribution
该方法已重命名,其 source 参数更名为 provider,且该参数现在接收 AdaptyExternalAttributionProvider 而非 String:
- Adapty.updateAttribution(attribution, "adjust")
+ Adapty.updateExternalAttribution(attribution, AdaptyExternalAttributionProvider.ADJUST)
归因数据仍为 Map<String, Any>。
调用会在后端接受数据进行异步处理后返回。返回成功并不意味着数据已应用到用户画像。
AdaptyExternalAttributionProvider
该 provider 现在是一个包含预定义值的类型:APPLE_ADS、ADJUST、APPSFLYER、BRANCH、TENJIN 和 CUSTOM。对于其他 provider,可通过其标识符构造:
AdaptyExternalAttributionProvider("your_provider")
直接构造的方式同样适用于 Adapty 在此 SDK 版本发布后新增的 provider——标识符会原样传递到后端,而不会被归并为未知值。标识符首尾的空白字符会自动去除。
每个预定义值都对应你之前传递给 updateAttribution 的同一个标识符:AdaptyExternalAttributionProvider.APPLE_ADS.value 的值为 apple_search_ads,其余值均为各自的小写名称。
AdaptyProfile.appliedAttributionSources → appliedExternalAttributionProviders
列出已应用于用户画像的归因提供商的属性已重命名,其元素类型也随之更改:
- if (profile.appliedAttributionSources.contains("apple_search_ads")) {
+ if (profile.appliedExternalAttributionProviders.contains(AdaptyExternalAttributionProvider.APPLE_ADS)) {
// Apple Ads attribution has been applied
}
AdaptyPaywallProductSubscription → AdaptyProductSubscription
订阅详情类型已重命名,因为推广产品现在使用相同的类型。仅名称发生变化——所有属性的名称和类型保持不变:
- val subscription: AdaptyPaywallProductSubscription? = product.subscription
+ val subscription: AdaptyProductSubscription? = product.subscription
App Store 内购推广
SDK 4.1 支持将 App Store 产品页上推广的内购项目传递给 iOS 应用。早期版本会自动完成此类购买,应用无法拦截。从 4.1 版本开始,购买流程会等待您的代码介入,因此即使您从未涉及过推广内购,也需要针对此变更进行相应处理。
要支持推广购买,请注册一个 OnPromotedPurchaseListener,并通过将产品传递给 Adapty.makePromotedPurchase 来完成购买。如果未注册监听器,购买将被挂起而无法完成:用户在 App Store 页面点击 Buy 后,应用中什么也不会发生。请尽早注册监听器——有关时机和完整示例,请参阅来自 App Store 的应用内购买。
选择特定布局
createFlowView、createNativeFlowView 和 AdaptyUIFlowPlatformView 新增了一个可选参数 customLayoutId。传入该参数可在流程的布局配置中渲染指定布局,而不使用 SDK 根据设备类型和屏幕尺寸自动选择的布局。目前 Flow & Paywall Builder 尚未支持分配自定义布局 ID,因此请保持该参数为空:
AdaptyUI.createFlowView(flow, customLayoutId = "tablet_landscape")
如果没有任何布局与该 ID 匹配,流程将在没有视图配置的情况下加载。该参数是可选的,默认值为 null,因此现有调用不受影响。
默认行为变更
这些变更不会导致编译错误,请在运行时进行测试:
- 购买完成:在 v3 中,默认的
paywallViewDidFinishPurchase会在除AdaptyPurchaseResult.UserCanceled以外的任何购买结果后关闭视图。在 v4 中,默认的flowViewDidFinishPurchase不执行任何操作,因此购买完成后流程会保持打开状态,直到你主动关闭它——与 iOS 行为一致。如果你依赖之前的自动关闭逻辑,请在购买完成后自行调用view.dismiss()。 - Android 系统返回:在 v3 中,默认的
paywallViewDidPerformAction会在CloseAction和AndroidSystemBackAction时关闭视图。在 v4 中,默认行为仅处理CloseAction——系统返回按钮不再自动关闭流程,与 iOS 保持一致(iOS 上流程无法通过系统手势关闭)。请为用户提供明确的退出方式(如 Close 按钮或on_device_back动作),或在flowViewDidPerformAction中自行关闭视图。 - 视图错误:在 v3 中,默认的
paywallViewDidFailRendering不执行任何操作。在 v4 中,默认的flowViewDidReceiveError会关闭视图——如需保持视图打开或自定义错误处理逻辑,请覆盖该方法。 - 视图仅可使用一次:调用
dismiss()后,视图将被销毁。如需再次展示流程,请重新调用createFlowView。
用户引导 API 弃用
旧版用户引导 API 在 v4 中已被弃用,请改用 Flow & 付费墙编辑工具。该 API 目前仍可使用,但将在未来版本中移除,请提前将您的用户引导迁移至 Flow & 付费墙编辑工具。
已弃用的符号:getOnboarding、getOnboardingForDefaultAudience、AdaptyUI.createOnboardingView、AdaptyUI.createNativeOnboardingView 以及 AdaptyUIOnboardingsEventsObserver。