Migrate Adapty Kotlin Multiplatform SDK sang v. 4.0

Adapty Kotlin Multiplatform SDK 4.0 (beta) giới thiệu các flow và đổi tên các API paywall tương ứng. Các API mới hoạt động với cả Flow Builder mới lẫn Paywall Builder hiện có — không cần thay đổi cấu hình nào trên Adapty Dashboard.

Tài liệu tham khảo nhanh

v3v4
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)
AdaptyPaywallAdaptyFlow
AdaptyUI.createPaywallView(paywall, ...)AdaptyUI.createFlowView(flow, ...)
AdaptyUI.createNativePaywallView(...)AdaptyNativePaywallViewAdaptyUI.createNativeFlowView(...)AdaptyNativeFlowView
AdaptyUIPaywallViewAdaptyUIFlowView
AdaptyUI.presentPaywallView(view) / dismissPaywallView(view)AdaptyUI.presentFlowView(view) / dismissFlowView(view)
AdaptyUI.setPaywallsEventsObserver(observer)AdaptyUI.setFlowsEventsObserver(observer)
AdaptyUI.registerPaywallEventsListener / unregisterPaywallEventsListenerAdaptyUI.registerFlowEventsListener / unregisterFlowEventsListener
AdaptyUIPaywallsEventsObserverAdaptyUIFlowsEventsObserver
AdaptyUIPaywallPlatformView(paywall, ...)AdaptyUIFlowPlatformView(flow, ...)
paywallViewDidPerformAction, paywallViewDidAppear, và các callback paywallView... khácflowViewDidPerformAction, flowViewDidAppear, và các callback flowView... khác
paywallViewDidFailRenderingflowViewDidReceiveError

AdaptyPaywallProduct giữ nguyên tên — sản phẩm vẫn thuộc về một flow, và getPaywallProducts cũng giữ nguyên tên, giờ nhận vào một AdaptyFlow. Các phương thức getFlowgetFlowForDefaultAudience không còn nhận tham số locale nữa. Các API mua hàng và hồ sơ người dùng (makePurchase, restorePurchases, getProfile, identify, updateProfile) cùng với fallback qua setFallback vẫn không thay đổi. Các phương thức onboarding vẫn hoạt động nhưng đã bị deprecated — xem Deprecation của Onboarding API. Một số hành vi mặc định đã thay đổi — xem Thay đổi hành vi mặc định.

Cài đặt

v4.0 là bản pre-release, vì vậy hãy ghim đúng phiên bản — Gradle không tự chọn các phiên bản pre-release thông qua dynamic ranges:

[versions]
adapty-kmp = "4.0.0-beta.1"

[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" }

Module adapty-kmp-ui chỉ cần thiết nếu bạn render flow và paywall bằng layer Compose Multiplatform (view.present()). Xem Cài đặt Adapty SDK để biết hướng dẫn thiết lập đầy đủ.

Các native Adapty SDK bên dưới đã được nâng lên phiên bản 4.x trên cả hai nền tảng và được resolve tự động — không cần thay đổi cấu hình build. iOS deployment target vẫn là 15.0, không thay đổi trong bản phát hành này.

Tải flows

getPaywall → getFlow

Kiểu trả về thay đổi từ AdaptyPaywall thành AdaptyFlow, và tham số locale bị loại bỏ — khi bạn render một flow, locale sẽ được tự động xác định; đối với paywall tùy chỉnh, tất cả các locale được trả về trong flow.remoteConfigs:

- Adapty.getPaywall("YOUR_PLACEMENT_ID", locale = "en")
-     .onSuccess { paywall ->
-         // use the paywall
+ Adapty.getFlow("YOUR_PLACEMENT_ID")
+     .onSuccess { flow ->
+         // use the flow
      }
      .onError { error ->
          // handle the error
      }

getPaywallForDefaultAudience được đổi tên tương tự:

- Adapty.getPaywallForDefaultAudience("YOUR_PLACEMENT_ID", locale = "en")
+ Adapty.getFlowForDefaultAudience("YOUR_PLACEMENT_ID")

getPaywallProducts(paywall) → getPaywallProducts(flow)

getPaywallProducts giữ nguyên tên nhưng bây giờ nhận vào một AdaptyFlow:

- Adapty.getPaywallProducts(paywall)
+ Adapty.getPaywallProducts(flow)
      .onSuccess { products ->
          // use the products
      }

Mô hình dữ liệu

getFlow trả về một AdaptyFlow thay vì AdaptyPaywall, và cấu trúc object đã thay đổi:

Thuộc tính AdaptyPaywall v3Thuộc tính AdaptyFlow v4Hành động
remoteConfig: AdaptyRemoteConfig? (đơn lẻ)remoteConfigs: List<AdaptyRemoteConfig>Một flow mang một Remote Config cho mỗi ngôn ngữ được cấu hình. Đọc cái phù hợp với người dùng: flow.remoteConfigs.firstOrNull { it.locale == "en" }.
(mới)paywalls: List<AdaptyFlowPaywall>Mỗi mục là một biến thể paywall trong flow, với name, variationId, và productIdentifiers riêng. Các phương thức web paywall nhận một AdaptyFlowPaywall — xem Phương thức web paywall.
productIdentifiersđã chuyểnĐịnh danh sản phẩm giờ nằm trên mỗi biến thể: flow.paywalls[i].productIdentifiers. Để lấy sản phẩm, tiếp tục gọi getPaywallProducts(flow).
hasViewConfigurationđã xóaXóa mọi kiểm tra hasViewConfiguration khỏi code của bạn — createFlowView sẽ trả về lỗi thay thế (xem Hiển thị flow).

hasViewConfiguration vẫn còn trên AdaptyOnboarding — chỉ có flow model là bỏ nó đi.

Phương thức Web paywall

openWebPaywallcreateWebPaywallUrl giữ nguyên tên, nhưng tham số paywall được thay thế bằng tham số flowPaywall nhận một AdaptyFlowPaywall — một trong các biến thể trong flow.paywalls. Bạn vẫn có thể truyền vào một AdaptyPaywallProduct thay thế:

- Adapty.openWebPaywall(paywall = paywall)
+ flow.paywalls.firstOrNull()?.let { flowPaywall ->
+     Adapty.openWebPaywall(flowPaywall = flowPaywall)
+ }

Theo dõi lượt xem flow

logShowPaywall → logShowFlow

logShowPaywall được đổi tên thành logShowFlow và nhận vào một AdaptyFlow. Sự kiện vẫn được ghi nhận theo cùng một biến thể, vì vậy các chỉ số funnel và A/B test hiện có vẫn hoạt động bình thường mà không cần thay đổi gì trên dashboard.

- Adapty.logShowPaywall(paywall)
+ Adapty.logShowFlow(flow)

Giống như trong v3, bạn không cần gọi phương thức này khi hiển thị các flow hoặc paywall được dựng bởi Flow Builder hoặc Paywall Builder — Adapty tự động theo dõi các lượt xem đó.

Hiển thị flows

createPaywallView → createFlowView

Đổi tên phương thức factory và truyền vào AdaptyFlow. Kiểu view trả về được đổi tên từ AdaptyUIPaywallView thành AdaptyUIFlowView, nhưng các phương thức (present, dismiss) và các tham số tùy chọn (loadTimeout, preloadProducts, customTags, customTimers, customAssets, productPurchaseParams) vẫn không thay đổi:

- AdaptyUI.createPaywallView(paywall)
+ AdaptyUI.createFlowView(flow)
      .onSuccess { view ->
          view.present()
      }
      .onError { error ->
          // handle the error
      }

Nếu bạn không sử dụng Compose Multiplatform, phương thức factory native cũng được đổi tên tương tự:

- AdaptyUI.createNativePaywallView(paywall)
+ AdaptyUI.createNativeFlowView(flow)

createFlowView trả về AdaptyResult.Error nếu flow không có view được cấu hình — điều này thay thế cho kiểm tra hasViewConfiguration ở v3:

- 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
+     }

Flow view chỉ dùng được một lần: sau khi gọi dismiss(), view sẽ bị huỷ, vì vậy hãy gọi lại createFlowView nếu muốn hiển thị flow thêm lần nữa.

Xử lý sự kiện

Observer sự kiện được đổi tên từ AdaptyUIPaywallsEventsObserver thành AdaptyUIFlowsEventsObserver, và các callback của nó thay đổi tiền tố paywallView thành flowView. Nội dung các handler hiện có không cần thay đổi code — chỉ cần đổi tên kiểu và các override:

- 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
      }
  })

Một callback cũng được đổi tên: paywallViewDidFailRendering thành flowViewDidReceiveError. Callback này kích hoạt cho các lỗi render như trước, cộng thêm các lỗi runtime không liên quan đến mua hàng:

- override fun paywallViewDidFailRendering(view: AdaptyUIPaywallView, error: AdaptyError) {}
+ override fun flowViewDidReceiveError(view: AdaptyUIFlowView, error: AdaptyError) {}

Xem Xử lý sự kiện flow & paywall để biết danh sách đầy đủ các callback.

Compose platform view

Nếu bạn nhúng view bằng composable Compose Multiplatform, AdaptyUIPaywallPlatformView(paywall, ...) được đổi tên thành AdaptyUIFlowPlatformView(flow, ...). Các callback sự kiện vẫn giữ tên onDid..., ngoại trừ onDidFailRendering được đổi thành onDidReceiveError:

- AdaptyUIPaywallPlatformView(
-     paywall = paywall,
+ AdaptyUIFlowPlatformView(
+     flow = flow,
      onDidFinishPurchase = { view, product, result -> /* ... */ },
  )

Giống như trong v3, các callback bạn truyền vào đây (và bất kỳ observer nào được đăng ký qua registerFlowEventsListener) chạy bổ sung vào global observer, không thay thế nó — callback của bạn quan sát một sự kiện; nó không thay thế hành vi mặc định toàn cục. Hãy lưu ý các thay đổi mặc định: ví dụ, hành vi mặc định toàn cục không còn tự động đóng view sau khi mua hàng nữa.

API Mới

  • AdaptyUI.setObserverModeResolver(...) với AdaptyUIObserverModeResolver — điều khiển các giao dịch mua và khôi phục được khởi tạo từ flow khi SDK chạy ở chế độ Observer. Trước đây, tính năng này chỉ có trong các SDK native iOS và Android. Xem Hiển thị flow trong chế độ Observer.
  • AdaptyUI.setSystemRequestsHandler(...) với AdaptyUISystemRequestsHandler — dành riêng cho các yêu cầu hệ thống từ flow (lời nhắc cấp quyền OS và yêu cầu đánh giá ứng dụng). Hiện tại flow chưa kích hoạt các yêu cầu này, nên bạn chưa cần đăng ký handler.
  • Callback tùy chọn mới flowViewDidReceiveAnalyticEvent được dành riêng cho các sự kiện phân tích tùy chỉnh từ flow. Hiện tại flow chưa phát ra các sự kiện này cho code của bạn, nên bạn chưa cần triển khai.
  • AdaptyUI.openWebUrl(url, openIn)AdaptyUI.requestAppReview() — hỗ trợ xử lý mặc định OpenUrlActionhandleAppReviewRequest mặc định, giúp xử lý URL và lời nhắc đánh giá ứng dụng ngay lập tức mà không cần cấu hình thêm. Chỉ gọi trực tiếp khi bạn ghi đè các giá trị mặc định đó.
  • AdaptyConfig.ServerCluster.CN — tùy chọn cụm máy chủ mới bên cạnh DEFAULTEU, dùng để kết nối ứng dụng với máy chủ China của Adapty.

Thay đổi hành vi mặc định

Những thay đổi này không gây ra lỗi biên dịch, vì vậy hãy kiểm tra chúng ở runtime:

  • Hoàn tất mua hàng: Trong v3, paywallViewDidFinishPurchase mặc định sẽ đóng view sau mọi kết quả mua hàng ngoại trừ AdaptyPurchaseResult.UserCanceled. Trong v4, flowViewDidFinishPurchase mặc định là no-op, tức là flow vẫn mở sau khi mua hàng cho đến khi bạn tự đóng nó — giống hành vi trên iOS. Nếu bạn phụ thuộc vào tính năng tự đóng đó, hãy tự gọi view.dismiss() sau khi mua hàng xong.
  • Nút back hệ thống Android: Trong v3, paywallViewDidPerformAction mặc định sẽ đóng view với cả CloseAction lẫn AndroidSystemBackAction. Trong v4, hành vi mặc định chỉ xử lý CloseActionnút back hệ thống không còn tự đóng flow nữa, giống iOS, nơi flow không thể bị đóng bằng thao tác hệ thống. Hãy cung cấp cho người dùng cách thoát rõ ràng (nút Close hoặc hành động on_device_back), hoặc tự đóng view trong flowViewDidPerformAction.
  • Lỗi view: Trong v3, paywallViewDidFailRendering mặc định không làm gì. Trong v4, flowViewDidReceiveError mặc định sẽ đóng view — hãy override nó nếu bạn muốn giữ view mở hoặc xử lý lỗi theo cách khác.
  • View chỉ dùng một lần: Sau khi gọi dismiss(), view sẽ bị hủy. Gọi lại createFlowView để hiển thị flow thêm một lần nữa.

Ngừng hỗ trợ Onboarding API

Onboarding API cũ đã bị ngừng hỗ trợ trong v4.0, thay thế bằng Flow Builder. API này vẫn hoạt động, nhưng sẽ bị xóa trong phiên bản tương lai, vì vậy hãy lên kế hoạch migration các onboarding của bạn sang Flow Builder.

Các ký hiệu đã ngừng hỗ trợ: getOnboarding, getOnboardingForDefaultAudience, AdaptyUI.createOnboardingView, AdaptyUI.createNativeOnboardingView, và AdaptyUIOnboardingsEventsObserver.