Hiển thị paywall nhắm mục tiêu AA ngay lần khởi chạy đầu tiên trong React Native SDK
Bài viết này áp dụng cho bản build iOS của ứng dụng. Attribution Apple Ads chỉ tồn tại trên iOS.
Attribution từ Apple Ads (AA) được nhận không đồng bộ sau khi gọi adapty.activate(). Ở lần khởi chạy đầu tiên, thường thì dữ liệu này chưa về kịp, nên getFlow sẽ phân giải theo đối tượng mặc định và người dùng Apple Ads sẽ bỏ lỡ paywall được nhắm mục tiêu theo AA. Thay vì chờ attribution về rồi mới hiển thị paywall, hãy hiển thị ngay một paywall và làm mới nó khi attribution AA được áp dụng — để người dùng Apple Ads nhận được biến thể đúng mục tiêu còn những người khác không phải chờ. AdaptyProfile.appliedExternalAttributionProviders cho bạn biết khi nào attribution AA đã được áp dụng.
Thuộc tính này chỉ báo cáo Apple Ads. Attribution từ các nhà cung cấp khác vẫn hiển thị trên hồ sơ người dùng và có thể dùng trong bộ lọc phân khúc, nhưng chưa hiển thị ở đây.
Trước khi bắt đầu
Bạn cần:
- Adapty React Native SDK 4.1 trở lên. Với phiên bản 3.17.1–4.0.x, thuộc tính profile có tên là
appliedAttributionSourcesvà flow được lấy bằnggetPaywall. - Apple Ads đã được cấu hình cho ứng dụng trong Adapty. Xem Apple Ads.
Cách hoạt động
Sau khi gọi adapty.activate(), SDK sẽ yêu cầu dữ liệu Apple Ads attribution từ Apple ở nền và chuyển kết quả về backend của Adapty. Khi AA trở thành nguồn attribution đang hoạt động cho hồ sơ người dùng, SDK sẽ gửi một AdaptyProfile đã cập nhật tới listener onLatestProfileLoad của bạn, với 'apple_search_ads' trong mảng appliedExternalAttributionProviders.
Điều này cho phép bạn tải paywall theo hai bước:
- Gọi
getFlowngay lập tức. Vì chưa có attribution nào được áp dụng, Adapty sẽ xử lý yêu cầu dựa trên đối tượng mặc định, và người dùng sẽ thấy paywall ngay. - Khi
'apple_search_ads'xuất hiện, gọi lạigetFlow. Lúc này Adapty xử lý yêu cầu dựa trên đối tượng Apple Ads và trả về paywall được nhắm mục tiêu, thay thế paywall đầu tiên.
appliedExternalAttributionProviders có thể rỗng hoặc vắng mặt. Điều đó có nghĩa là một trong các trường hợp sau:
- Attribution từ Apple Ads chưa được xử lý cho hồ sơ người dùng này.
- Chưa có attribution nào đến.
- Attribution đến từ một nhà cung cấp khác, không được báo cáo trong mảng này.
Trong cả ba trường hợp, bước 1 vẫn an toàn — Adapty xử lý yêu cầu dựa trên đối tượng phù hợp với trạng thái hồ sơ người dùng hiện tại, thường là đối tượng mặc định. Bước 2 chỉ chạy khi 'apple_search_ads' xuất hiện.
Ở mỗi lần khởi động tiếp theo, hồ sơ người dùng đã được lưu cache sẽ mang sẵn 'apple_search_ads' trong appliedExternalAttributionProviders, vì vậy lần gọi getFlow đầu tiên đã trả về paywall được phân khúc theo Apple Ads — không có lần tải thứ hai hay thay đổi nào hiển thị. Luồng hai bước chỉ quan trọng ở lần khởi động đầu tiên, khi attribution vẫn đang được xử lý.
Triển khai
Hiển thị paywall ngay lập tức, sau đó lắng nghe 'apple_search_ads' và làm mới paywall khi nó xuất hiện.
- Kích hoạt SDK. Xem Cài đặt & cấu hình React Native SDK.
- Tải và hiển thị paywall với
getFlownhư thông thường — không chờ đợi attribution. - Đăng ký nhận cập nhật hồ sơ người dùng với
adapty.addEventListener('onLatestProfileLoad', …)và theo dõi'apple_search_ads'. Khi nó xuất hiện, tải lại paywall và hiển thị paywall đã được cập nhật. Nếu bạn chưa thiết lập listener, xem Lắng nghe cập nhật gói đăng ký:
const subscription = adapty.addEventListener('onLatestProfileLoad', async profile => {
if (!profile.appliedExternalAttributionProviders?.includes('apple_search_ads')) return;
const targeted = await adapty.getFlow(placementId);
// present the targeted paywall in place of the first one
});
// Call subscription.remove() after the upgrade, or after a timeout (see below).
- Dừng lắng nghe sau một khoảng thời gian. Hầu hết người dùng không bao giờ nhận được attribution Apple Ads, vì vậy hãy xóa listener sau một khoảng thời gian thay vì giữ nó mở suốt phiên. Cấu hình paywall dự phòng cho placement để người dùng luôn thấy gì đó nếu yêu cầu thất bại.
Ví dụ hoàn chỉnh
onAppleAdsAttribution sẽ resolve khi attribution Apple Ads được áp dụng, hoặc reject sau timeoutMs. Đoạn code bên dưới tải paywall ngay lập tức, sau đó tải lại khi attribution đến — người dùng Apple Ads nhận được paywall nhắm mục tiêu, và nếu attribution không bao giờ đến thì paywall đầu tiên vẫn được giữ nguyên:
const APPLE_ADS_PROVIDER = 'apple_search_ads';
const placementId = 'YOUR_PLACEMENT_ID';
function hasAppleAdsAttribution(profile: AdaptyProfile): boolean {
return profile.appliedExternalAttributionProviders?.includes(APPLE_ADS_PROVIDER) ?? false;
}
/**
* Resolves once Apple Ads attribution is applied to the profile.
* Rejects with a timeout error if attribution never arrives within `timeoutMs`.
* Call after `adapty.activate()`.
*/
export function onAppleAdsAttribution(timeoutMs: number): Promise<void> {
return new Promise((resolve, reject) => {
let timer: ReturnType<typeof setTimeout> | undefined;
let subscription: { remove: () => void } | undefined;
const stop = () => {
clearTimeout(timer);
subscription?.remove();
};
subscription = adapty.addEventListener('onLatestProfileLoad', profile => {
if (!hasAppleAdsAttribution(profile)) return;
stop();
resolve();
});
timer = setTimeout(() => {
stop();
reject(new Error(`Apple Ads attribution timed out after ${timeoutMs}ms`));
}, timeoutMs);
});
}
let flow = await adapty.getFlow(placementId);
onAppleAdsAttribution(30_000)
.then(() => adapty.getFlow(placementId))
.then(updated => {
flow = updated;
})
.catch(() => {
console.log('Apple Ads attribution or loading failed');
});
Ở lần khởi chạy đầu tiên, người dùng Apple Ads sẽ thấy paywall mặc định trong một khoảnh khắc trước khi nó được thay thế. Nếu bạn hiển thị paywall bằng Paywall Builder, hãy cân nhắc xem việc hiển thị lại có phù hợp không, hoặc chỉ áp dụng bản cập nhật trước khi paywall được hiển thị. Điều chỉnh timeoutMs tùy theo thời gian bạn sẵn sàng lắng nghe — attribution khi đến thường xuất hiện trong vài giây sau khi khởi chạy.
Nếu ứng dụng của bạn đã lắng nghe onLatestProfileLoad cho các mục đích khác (ví dụ, kiểm tra trạng thái gói đăng ký), bạn không cần thay đổi gì. adapty.addEventListener hỗ trợ nhiều listener độc lập, nên listener này sẽ được thêm vào mà không ảnh hưởng đến các listener khác.