Migrate Adapty React Native SDK sang v. 4.0
Adapty React Native SDK 4.0 (beta) giới thiệu flows 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 và Paywall Builder hiện có — không cần thay đổi cấu hình nào trên Adapty Dashboard.
Tham khảo nhanh
| v3 | v4 |
|---|---|
adapty.getPaywall(placementId, locale?, params?) | adapty.getFlow(placementId, params?) |
adapty.getPaywallForDefaultAudience(placementId, locale?, params?) | adapty.getFlowForDefaultAudience(placementId, params?) |
adapty.getPaywallProducts(paywall) | adapty.getPaywallProducts(flow) |
adapty.logShowPaywall(paywall) | adapty.logShowFlow(flow) |
AdaptyPaywall (kiểu) | AdaptyFlow |
createPaywallView(paywall) | createFlowView(flow) |
AdaptyPaywallView (component) | AdaptyFlowView |
EventHandlers (kiểu) | FlowEventHandlers |
onPaywallShown | onAppeared |
onPaywallClosed | onDisappeared |
onRenderingFailed | onError |
AdaptyPaywallProduct vẫn giữ nguyên tên — sản phẩm vẫn thuộc về một flow, và getPaywallProducts giờ nhận vào một AdaptyFlow. Các phương thức getFlow và getFlowForDefaultAudience không còn nhận tham số locale nữa. Các phương thức view present, dismiss, setEventHandlers, và showDialog, cùng các event handler onCloseButtonPress, onUrlPress, onCustomAction, onProductSelected, onPurchaseStarted, onPurchaseCompleted, onPurchaseFailed, onRestoreStarted, onRestoreCompleted, onRestoreFailed, onLoadingProductsFailed, onWebPaymentNavigationFinished, và onAndroidSystemBack vẫn giữ nguyên tên như trong v3. Một số hành vi mặc định đã thay đổi — xem Thay đổi hành vi mặc định. |
Phiên bản iOS tối thiểu
Adapty React Native SDK 4.0 nâng phiên bản iOS deployment target tối thiểu từ iOS 13.0 lên iOS 15.0. Hãy đặt iOS deployment target của bạn thành 15.0 hoặc cao hơn trước khi nâng cấp.
Cài đặt
Cập nhật gói
v4.0 là bản phát hành thử nghiệm (pre-release), vì vậy hãy chỉ định chính xác phiên bản — npm không tự động chọn các phiên bản pre-release qua cú pháp caret/tilde:
npm install [email protected]
# or
yarn add [email protected]
iOS: các SDK gốc hiện được phân phối qua Swift Package Manager
Kho spec của CocoaPods sẽ chuyển sang chế độ chỉ đọc vào tháng 12 năm 2026, vì vậy kể từ v4, các SDK gốc Adapty, AdaptyUI, và AdaptyPlugin không còn được kéo vào dưới dạng sub-dependency của CocoaPods nữa — podspec sẽ kéo chúng thông qua Swift Package Manager (thông qua helper spm_dependency). Điều này yêu cầu hai thứ:
- React Native 0.75 trở lên — cần thiết cho helper
spm_dependencytrong podspec. Nếu dùng phiên bản cũ hơn,pod installsẽ báo lỗi; hãy nâng cấp React Native trước, hoặc tiếp tục dùngreact-native-adapty3.x. - Dynamic frameworks — Các dependency SPM yêu cầu liên kết động. Cách bật tính năng này khác nhau giữa Expo và React Native thuần.
Expo
Thêm config plugin expo-build-properties và đặt iOS frameworks thành dynamic trong app.json (hoặc app.config.js):
{
"expo": {
"plugins": [
[
"expo-build-properties",
{
"ios": {
"useFrameworks": "dynamic"
}
}
]
]
}
}
Sau đó cài plugin và tạo lại native project:
npx expo install expo-build-properties
npx expo prebuild --clean
Bare React Native
Thêm dynamic frameworks vào iOS target, sau đó cài lại pods:
use_frameworks! :linkage => :dynamic
cd ios && pod install --repo-update
Nếu trước đây bạn đã thêm Adapty, AdaptyUI, hoặc AdaptyPlugin dưới dạng sub-dependencies của CocoaPods, hãy xóa các dòng pod 'Adapty', pod 'AdaptyUI', hoặc pod 'AdaptyPlugin' khỏi Podfile trước.
Chuyển từ liên kết tĩnh mặc định sang dynamic frameworks có thể xung đột với các thư viện chưa hỗ trợ modular headers, và không tương thích với Flipper. Nếu gặp lỗi build, xem bài viết này về tích hợp Swift Package Manager với các thư viện React Native.
Xem Cài đặt Adapty SDK để biết hướng dẫn thiết lập đầy đủ.
Lấy flows
getPaywall → getFlow
Kiểu trả về thay đổi từ AdaptyPaywall sang AdaptyFlow, và tham số locale bị loại bỏ — khi bạn render một flow, locale được tự động xác định; với các paywall tùy chỉnh, tất cả các locale được trả về trong flow.remoteConfigs:
- const paywall = await adapty.getPaywall('YOUR_PLACEMENT_ID', 'en');
+ const flow = await adapty.getFlow('YOUR_PLACEMENT_ID');
getPaywallForDefaultAudience được đổi tên theo cách tương tự:
- const paywall = await adapty.getPaywallForDefaultAudience('YOUR_PLACEMENT_ID', 'en');
+ const flow = await adapty.getFlowForDefaultAudience('YOUR_PLACEMENT_ID');
getPaywallProducts(paywall) → getPaywallProducts(flow)
getPaywallProducts giữ nguyên tên nhưng giờ nhận một AdaptyFlow:
- const products = await adapty.getPaywallProducts(paywall);
+ const products = await adapty.getPaywallProducts(flow);
Mô hình dữ liệu
getFlow trả về một AdaptyFlow thay vì AdaptyPaywall, và cấu trúc của đối tượng đã thay đổi:
Trường AdaptyPaywall v3 | Trường AdaptyFlow v4 | Hành động |
|---|---|---|
remoteConfig? (đơn) | remoteConfigs?: AdaptyRemoteConfig[] (mảng) | Một flow chứa 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?.find((c) => c.lang === 'en'). |
products | flow.paywalls[i].productIdentifiers | Các mã định danh sản phẩm giờ nằm trên từng biến thể của flow, không phải trên flow. |
webPurchaseUrl? | flow.paywalls[i].webPurchaseUrl | Đã chuyển từ flow sang từng biến thể paywall. |
version?: number | flowVersionId?: string | Đổi tên, và kiểu dữ liệu thay đổi từ number sang string. |
hasViewConfiguration | đã xóa | Xóa mọi kiểm tra hasViewConfiguration khỏi code của bạn. |
requestLocale | đã xóa | Locale không còn là một phần của model nữa. |
| (mới) | paywalls: AdaptyFlowPaywall[] | Mỗi mục là một biến thể paywall trong flow. |
| (mới) | responseCreatedAt: number | Timestamp phản hồi từ server, tính bằng mili giây. |
| Product identifiers moved from the flow to each variation: |
- const ids = paywall.products;
+ const ids = flow.paywalls[0].productIdentifiers;
Các phương thức Web paywall
openWebPaywall và createWebPaywallUrl vẫn giữ nguyên tên, nhưng tham số đầu tiên bây giờ là AdaptyFlowPaywall (một biến thể flow) thay vì AdaptyPaywall. Bạn vẫn có thể truyền vào AdaptyPaywallProduct.
const flow = await adapty.getFlow('YOUR_PLACEMENT_ID');
- await adapty.openWebPaywall(paywall);
+ await adapty.openWebPaywall(flow.paywalls[0]);
Theo dõi lượt xem flow
logShowPaywall → logShowFlow
logShowPaywall được đổi tên thành logShowFlow và giờ nhận vào một AdaptyFlow. Sự kiện vẫn được ghi lại theo cùng một biến thể, nên 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 trên dashboard.
- await adapty.logShowPaywall(paywall);
+ await adapty.logShowFlow(flow);
Giống như ở 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ị flow
createPaywallView → createFlowView
Đổi tên hàm factory và truyền vào AdaptyFlow. Các phương thức của controller được trả về (present, dismiss, setEventHandlers, showDialog) không thay đổi:
- import { createPaywallView } from 'react-native-adapty';
+ import { createFlowView } from 'react-native-adapty';
- const view = await createPaywallView(paywall);
+ const view = await createFlowView(flow);
await view.present();
AdaptyPaywallView → AdaptyFlowView
Nếu bạn render bằng React component, hãy đổi tên component và truyền prop flow:
- import { AdaptyPaywallView } from 'react-native-adapty';
+ import { AdaptyFlowView } from 'react-native-adapty';
- <AdaptyPaywallView paywall={paywall} /* … */ />
+ <AdaptyFlowView flow={flow} /* … */ />
Một flow view được tạo bằng createFlowView chỉ dùng một lần: sau khi gọi dismiss(), view đó sẽ bị hủy, vì vậy hãy gọi lại createFlowView để hiển thị flow một lần nữa. Một AdaptyFlowView được nhúng vào sẽ bị đóng khi unmount — việc trả về true từ một handler không đóng embedded view, vì vậy hãy tự thay đổi state của bạn, ví dụ trong onCloseButtonPress.
Xử lý sự kiện
Giao diện event-handler được đổi tên từ EventHandlers thành FlowEventHandlers, và ba callback được đổi tên. Phần thân handler hiện có không cần thay đổi code — chỉ cần đổi tên:
- onPaywallShown: () => { /* … */ },
+ onAppeared: () => { /* … */ },
- onPaywallClosed: () => { /* … */ },
+ onDisappeared: () => { /* … */ },
- onRenderingFailed: (error) => { /* … */ },
+ onError: (error) => { /* … */ },
Tất cả các event handler khác vẫn giữ nguyên tên. Hai handler cũng có thêm tham số thứ hai: onPurchaseCompleted thành (purchaseResult, product) và onPurchaseFailed thành (error, product), trong đó product là AdaptyPaywallProduct liên quan. Xem Xử lý sự kiện flow & paywall để biết danh sách đầy đủ.
onDisappeared chỉ kích hoạt với flow được trình bày theo dạng modal bằng createFlowView().present(). Component AdaptyFlowView không hỗ trợ prop này — để ẩn một embedded view, hãy unmount nó.
v4 cũng bổ sung thêm một số tính năng bạn có thể tuỳ chọn bật:
- Phương thức
adapty.openWebUrl(url, openIn?)vàadapty.requestAppReview()— các phương thức này hỗ trợ các handler mặc địnhonUrlPressvàonRequestAppReview, nên URL và lời nhắc đánh giá ứng dụng được xử lý natively ngay từ đầu. Chỉ gọi trực tiếp khi bạn ghi đè các handler đó. - Xử lý giao dịch mua trong Observer mode bên trong flow thông qua các handler mới
onObserverPurchaseInitiated/onObserverRestoreInitiated. Xem Xử lý giao dịch mua trong Observer mode.
Các API đã bị xóa và deprecated
setFallbackPaywalls → setFallback
setFallbackPaywalls đã bị xóa. Hãy dùng setFallback, nhận cùng tham số:
- await adapty.setFallbackPaywalls(fileLocation);
+ await adapty.setFallback(fileLocation);
Các export đã bị xóa
Các symbol này không còn được export từ react-native-adapty nữa. Hãy xóa các import liên quan:
AdaptyPaywall: DùngAdaptyFlowthay thế.ProductReference: DùngAdaptyProductIdentifier, đọc từflow.paywalls[i].productIdentifiers.AdaptyPaywallBuilder: Đã bị xóa. Flow và paywall được render natively.AdaptyAndroidSubscriptionUpdateParameters: Dùng shape lồng nhausubscriptionUpdateParams(xem bên dưới).
activate: lockMethodsUntilReady
lockMethodsUntilReady đã bị xóa và hành vi này hiện luôn được bật. Hãy xóa nó khỏi lệnh gọi activate — giữ lại nó sẽ gây lỗi biên dịch:
- await adapty.activate('PUBLIC_SDK_KEY', { lockMethodsUntilReady: true });
+ await adapty.activate('PUBLIC_SDK_KEY');
Cập nhật gói đăng ký Android trong makePurchase
Cấu trúc phẳng cho việc cập nhật gói đăng ký Android đã bị loại bỏ. Hãy chuyển oldSubVendorProductId và prorationMode vào một object lồng nhau tên là subscriptionUpdateParams, và giữ isOfferPersonalized ở cấp cao nhất. Xem Thực hiện mua hàng để xem ví dụ đầy đủ.
Android: safe-area paddings
Tài nguyên boolean Android <bool name="adapty_paywall_enable_safe_area_paddings">…</bool> đã bị xóa. Hãy xóa nó khỏi res/values/bools.xml và kiểm soát safe-area paddings tại runtime bằng tham số enableSafeArea khi bạn tạo flow view. Mặc định là true cho kiểu hiển thị modal và false cho component nhúng.
Chế độ mock
Nếu bạn chạy SDK ở chế độ mock (Expo Go hoặc web preview), hãy đổi tên khóa cấu hình mock paywalls thành flows.
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 lúc runtime:
onAndroidSystemBack: Mặc định đã thay đổi từ đóng view sang giữ nguyên. Để khôi phục hành vi cũ, hãy trả vềtruetừ handler.onPurchaseCompleted: Mặc định đã thay đổi từ đóng view (trừ khi người dùng hủy mua) sang luôn giữ nguyên. Để khôi phục hành vi cũ, hãy trả vềpurchaseResult.type !== 'user_cancelled'từ handler.onRestoreCompleted: Mặc định đã thay đổi từ đóng view sau khi khôi phục thành công sang giữ nguyên. Để khôi phục hành vi cũ, hãy trả vềtruetừ handler.onUrlPress: Mặc định hiện tại sẽ mở URL thông qua tầng native, tuân theo cài đặt trình duyệt in-app hoặc bên ngoài từ dashboard. Ghi đè handler để tự xử lý việc mở URL.
Onboarding API không còn được hỗ trợ
Onboarding API cũ đã bị deprecated trong v4.0, thay thế bằng Flow Builder. API này vẫn hoạt động bình thường, và IDE của bạn sẽ đánh dấu các symbol bị deprecated thông qua annotation @deprecated — không có cảnh báo nào xuất hiện lúc runtime. Các symbol này sẽ bị xóa trong một bản phát hành 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 symbol bị deprecated: getOnboarding, getOnboardingForDefaultAudience, createOnboardingView, và AdaptyOnboardingView.