React Native - Hiển thị paywall mới bằng Paywall Builder
Nếu bạn đã tùy chỉnh paywall bằng Paywall Builder, bạn không cần lo lắng về việc render nó trong mã ứng dụng di động để hiển thị cho người dùng. Một paywall như vậy chứa cả nội dung cần hiển thị lẫn cách thức hiển thị.
Trước khi bắt đầu, hãy đảm bảo rằng:
- Bạn đã tạo một paywall.
- Bạn đã thêm paywall vào một placement.
- Bạn đã tải paywall và chuẩn bị view.
Hướng dẫn này chỉ dành cho paywall mới của Paywall Builder, yêu cầu SDK v3.0 trở lên. Quy trình hiển thị paywall khác nhau tùy theo phiên bản Paywall Builder và paywall dùng Remote Config.
- Để hiển thị paywall dùng Remote Config, xem Render paywall được thiết kế bằng Remote Config.
Adapty React Native SDK cung cấp hai cách để hiển thị paywall:
-
React component: Component được nhúng cho phép bạn tích hợp vào kiến trúc và hệ thống điều hướng của ứng dụng.
-
Hiển thị dạng modal
React component
Cách dùng React component yêu cầu SDK 3.14.0 trở lên.
Để nhúng paywall vào cây component hiện có của bạn, hãy dùng component AdaptyPaywallView trực tiếp trong hệ thống phân cấp component React Native. Component được nhúng cho phép bạn tích hợp vào kiến trúc và hệ thống điều hướng của ứng dụng.
Trên Android, nếu paywall không kéo dài ra sau thanh trạng thái, một lớp phủ trực quan có thể xuất hiện ở phía trên cùng. Chúng tôi khuyên bạn nên tắt tính năng này cho các paywall của mình. Xem Lớp phủ trực quan ở đầu paywall (Android).
function MyPaywall({ paywall }) {
const paywallParams = useMemo(() => ({
loadTimeoutMs: 3000,
}), []);
const onCloseButtonPress = useCallback<EventHandlers['onCloseButtonPress']>(() => {}, []);
const onProductSelected = useCallback<EventHandlers['onProductSelected']>((productId) => {}, []);
const onPurchaseStarted = useCallback<EventHandlers['onPurchaseStarted']>((product) => {}, []);
const onPurchaseCompleted = useCallback<EventHandlers['onPurchaseCompleted']>((purchaseResult, product) => {}, []);
const onPurchaseFailed = useCallback<EventHandlers['onPurchaseFailed']>((error, product) => {}, []);
const onRestoreStarted = useCallback<EventHandlers['onRestoreStarted']>(() => {}, []);
const onRestoreCompleted = useCallback<EventHandlers['onRestoreCompleted']>((profile) => {}, []);
const onRestoreFailed = useCallback<EventHandlers['onRestoreFailed']>((error) => {}, []);
const onPaywallShown = useCallback<EventHandlers['onPaywallShown']>(() => {}, []);
const onRenderingFailed = useCallback<EventHandlers['onRenderingFailed']>((error) => {}, []);
const onLoadingProductsFailed = useCallback<EventHandlers['onLoadingProductsFailed']>((error) => {}, []);
const onUrlPress = useCallback<EventHandlers['onUrlPress']>((url) => {}, []);
const onCustomAction = useCallback<EventHandlers['onCustomAction']>((actionId) => {}, []);
const onWebPaymentNavigationFinished = useCallback<EventHandlers['onWebPaymentNavigationFinished']>(() => {}, []);
return (
<AdaptyPaywallView
paywall={paywall}
params={paywallParams}
style={styles.paywall}
onCloseButtonPress={onCloseButtonPress}
onProductSelected={onProductSelected}
onPurchaseStarted={onPurchaseStarted}
onPurchaseCompleted={onPurchaseCompleted}
onPurchaseFailed={onPurchaseFailed}
onRestoreStarted={onRestoreStarted}
onRestoreCompleted={onRestoreCompleted}
onRestoreFailed={onRestoreFailed}
onPaywallShown={onPaywallShown}
onRenderingFailed={onRenderingFailed}
onLoadingProductsFailed={onLoadingProductsFailed}
onCustomAction={onCustomAction}
onUrlPress={onUrlPress}
onWebPaymentNavigationFinished={onWebPaymentNavigationFinished}
/>
);
}
Hiển thị dạng modal
Để hiển thị paywall dưới dạng màn hình độc lập, hãy dùng phương thức view.present() trên view được tạo bởi phương thức createPaywallView. Mỗi view chỉ có thể dùng một lần. Nếu bạn cần hiển thị paywall lại, hãy gọi createPaywallView thêm một lần nữa để tạo instance view mới.
Việc tái sử dụng cùng một view mà không tạo lại là không được phép. Điều này sẽ dẫn đến lỗi AdaptyUIError.viewAlreadyPresented.
Cấu hình kiểu trình bày trên iOS
Cấu hình cách paywall được hiển thị trên iOS bằng cách truyền tham số iosPresentationStyle vào phương thức present(). Tham số này chấp nhận giá trị 'full_screen' (mặc định) hoặc 'page_sheet'.
try {
await view.present(iosPresentationStyle: 'page_sheet');
} catch (error) {
// handle the error
}
Dùng bộ đếm thời gian do nhà phát triển định nghĩa
Để sử dụng bộ đếm thời gian do nhà phát triển định nghĩa trong ứng dụng di động, hãy dùng timerId, trong ví dụ này là CUSTOM_TIMER_NY — Timer ID của bộ đếm thời gian do nhà phát triển định nghĩa mà bạn đã đặt trong Adapty dashboard. Điều này đảm bảo ứng dụng của bạn cập nhật động bộ đếm thời gian với giá trị chính xác — như 13d 09h 03m 34s (được tính bằng thời gian kết thúc của bộ đếm, chẳng hạn Ngày đầu năm mới, trừ đi thời gian hiện tại).
Trong ví dụ này, CUSTOM_TIMER_NY là Timer ID của bộ đếm thời gian do nhà phát triển định nghĩa mà bạn đã đặt trong Adapty dashboard. timerResolver đảm bảo ứng dụng của bạn cập nhật động bộ đếm thời gian với giá trị chính xác — như 13d 09h 03m 34s (được tính bằng thời gian kết thúc của bộ đếm, chẳng hạn Ngày đầu năm mới, trừ đi thời gian hiện tại).
Hiển thị hộp thoại
Sử dụng phương thức này thay vì hộp thoại cảnh báo gốc khi một paywall view đang được hiển thị trên Android. Trên Android, các alert thông thường của RN xuất hiện phía sau paywall view, khiến người dùng không thể nhìn thấy chúng. Phương thức này đảm bảo hộp thoại được hiển thị đúng cách phía trên paywall trên tất cả các nền tảng.
try {
const action = await view.showDialog({
title: 'Close paywall?',
content: 'You will lose access to exclusive offers.',
primaryActionTitle: 'Stay',
secondaryActionTitle: 'Close',
});
if (action === 'secondary') {
// User confirmed - close the paywall
await view.dismiss();
}
// If primary - do nothing, user stays
} catch (error) {
// handle error
}
Thay thế một gói đăng ký bằng gói khác
Khi người dùng cố gắng mua một gói đăng ký mới trong khi đang có gói đăng ký khác hoạt động trên Android, bạn có thể kiểm soát cách xử lý giao dịch mới bằng cách truyền tham số cập nhật gói đăng ký khi tạo paywall view. Để thay thế gói đăng ký hiện tại bằng gói mới, hãy dùng productPurchaseParams trong createPaywallView với các tham số oldSubVendorProductId và prorationMode.
const productPurchaseParams = paywall.productIdentifiers.map((productId) => {
let params = {};
if (Platform.OS === 'android') {
params.android = {
subscriptionUpdateParams: {
oldSubVendorProductId: 'PRODUCT_ID_OF_THE_CURRENT_ACTIVE_SUBSCRIPTION',
prorationMode: 'with_time_proration',
},
};
}
return { productId, params };
});
const view = await createPaywallView(paywall, { productPurchaseParams });
Khắc phục sự cố
Lớp phủ trực quan ở đầu paywall (Android)
Cài đặt này được hỗ trợ từ React Native SDK 3.15.5 trở lên và chỉ khả dụng trong các dự án React Native thuần túy.
Nếu bạn đang dùng Expo managed workflow, bạn không thể thêm tài nguyên Android này trực tiếp. Để áp dụng cài đặt này, bạn phải tạo một Expo config plugin tùy chỉnh để thêm tài nguyên Android tương ứng và đăng ký nó trong app.config.js. Điều này là bắt buộc vì Expo quản lý dự án Android gốc cho bạn.
Nếu AdaptyPaywallView không kéo dài ra sau thanh trạng thái, một lớp phủ trực quan vẫn có thể xuất hiện ở phía trên cùng. Để xóa nó, hãy thêm tài nguyên boolean sau vào ứng dụng của bạn:
-
Đi đến
android/app/src/main/res/values. Nếu không có filebools.xml, hãy tạo file đó. -
Thêm tài nguyên sau:
<resources>
<bool name="adapty_paywall_enable_safe_area_paddings">false</bool>
</resources>
Lưu ý rằng các thay đổi này áp dụng cho tất cả paywall trong ứng dụng của bạn.