Pre-fetching Screens
This section provides details on how to pre-fetch Screens and display them later
Minimum SDK versions
- iOS: 3.5.0
- Android: 3.5.0
- ReactNative: 2.5.0
- Cordova: 2.5.0
- Flutter: 1.5.0
- Unity: 4.1.0
Purchasely, by default, shows the Screen with a loading indicator while fetching the Screen from the network and preparing it for display.
Using Purchasely.fetchPresentation()
method, you can pre-fetch the Screen from the network before displaying it. This provides the following benefits:
- Display the Screen only after it has been loaded from the network
- Handle network errors gracefully
- Show a custom loading screen
- Pre-load the Screen while users navigate through your app, such as during onboarding screens
- Choose not to display a Screen for a specific placement
- Display your own Screen
Implementation
Call Purchasely.fetchPresentation
for a placement or with a presentation id
- An error may be returned if the presentation could not be fetched from the network.
- If successful, you will have a
PLYPresentation
instance containing the following properties:
public class PLYSubscription: NSObject {
public var product: PLYProduct
public var plan: PLYPlan
public var subscriptionSource: PLYSubscriptionSource
public var nextRenewalDate: Date?
public var cancelledDate: Date?
public var originalPurchasedDate: Date?
public var purchasedDate: Date?
public var offerType: PLYSubscriptionOfferType
public var status: PLYSubscriptionStatus
public var environment: PLYSubscriptionEnvironment
public var storeCountry: String?
public var isFamilyShared: Bool
public var contentId: String?
public var offerIdentifier: String?
}
class PLYSubscriptionData(
val data: PLYSubscription,
val plan: PLYPlan,
val product: PLYProduct
)
class PLYSubscription(
val id: String? = null,
val storeType: StoreType? = null,
val purchaseToken: String? = null,
val planId: String? = null,
val cancelledAt: String? = null,
val nextRenewalAt: String? = null,
val originalPurchasedAt: String? = null,
val purchasedAt: String? = null,
val offerType: PLYOfferType? = PLYOfferType.NONE,
val environment: PLYEnvironment? = null,
val storeCountry: String? = null,
val isFamilyShared: Boolean? = null,
val contentId: String? = null,
val offerIdentifier: String? = null,
val subscriptionStatus: PLYSubscriptionStatus? = null,
val cumulatedRevenuesInUSD: Double? = null,
val subscriptionDurationInDays: Int? = null,
val subscriptionDurationInWeeks: Int? = null,
val subscriptionDurationInMonths: Int? = null,
)
type PurchaselySubscription = {
purchaseToken: string;
subscriptionSource: SubscriptionSource;
nextRenewalDate: string;
cancelledDate: string;
plan: PurchaselyPlan;
product: PurchaselyProduct;
};
class PLYSubscription {
String? purchaseToken;
PLYSubscriptionSource? subscriptionSource;
String? nextRenewalDate;
String? cancelledDate;
PLYPlan? plan;
PLYProduct? product;
}
public class SubscriptionData
{
public Plan plan;
public Product product;
public string contentId;
public string environment;
public string id;
public bool isFamilyShared;
public string offerIdentifier;
public SubscriptionOfferType offerType;
public string originalPurchasedAt;
public string purchaseToken;
public string purchasedDate;
public string nextRenewalDate;
public string cancelledDate;
public string storeCountry;
public StoreType storeType;
public SubscriptionStatus status;
}
subscription.id;
subscription.storeType;
subscription.purchaseToken;
subscription.planId;
subscription.cancelledAt;
subscription.nextRenewalAt;
subscription.originalPurchasedAt;
subscription.purchasedAt;
subscription.plans
subscription.offerType;
subscription.environment;
subscription.storeCountry;
subscription.isFamilyShared;
subscription.contentId;
subscription.offerIdentifier;
subscription.subscriptionStatus;
subscription.cumulatedRevenuesInUSD;
subscription.subscriptionDurationInDays;
subscription.subscriptionDurationInWeeks;
subscription.subscriptionDurationInMonths;
A presentation can be one of the following types:
- Normal: The default behavior, a Purchasely Screen created from our console.
- Fallback: A Purchasely Screen, but not the one you requested, as it could not be found.
- Deactivated: No Screen associated with that placement, possibly for a specific A/B test or an audience.
- Client: You declared your own Screen in our console and should display it. Use the list of plans to determine which offers to display to your users.
// fetch presentation for placement
Purchasely.fetchPresentation(
for: "onboarding",
fetchCompletion: { presentation, error in
// closure to get presentation and display it
guard let presentation = presentation, error == nil else {
print("Error while fetching presentation: \(error?.localizedDescription ?? "unknown")")
return
}
if presentation.type == .normal || presentation.type == .fallback {
let screenController = presentation.controller
// display controller.
} else if presentation.type == .deactivated {
// nothing to display
} else if presentation.type == .client {
let presentationId = presentation.id
let planIds = presentation.plans
// display your own Screen
}
},
completion: { result, plan in
// closure when presentation controller is closed to get result
switch result {
case .purchased:
print("User purchased: \(plan?.name)")
break
case .restored:
print("User restored: \(plan?.name)")
break
case .cancelled:
break
@unknown default:
break
}
}
)
Purchasely.fetchPresentationForPlacement("onboarding") { presentation, error ->
if(error != null) {
Log.d("Purchasely", "Error fetching Screen", error)
return@fetchPresentationForPlacement
}
when(presentation?.type) {
PLYPresentationType.NORMAL,
PLYPresentationType.FALLBACK -> {
val screenView = presentation.buildView(
context = this@MainActivity,
viewProperties = PLYPresentationViewProperties(
onClose = {
// TODO remove view from your layout
}
)
) { result, plan ->
// Screen is closed, check result to know if a purchase happened
when(result) {
PLYProductViewResult.PURCHASED -> Log.d("Purchasely", "User purchased ${plan?.name}")
PLYProductViewResult.CANCELLED -> Log.d("Purchasely", "User cancelled purchased")
PLYProductViewResult.RESTORED -> Log.d("Purchasely", "User restored ${plan?.name}")
}
}
// Display Purchasely Screen by adding screenView to your layout
}
PLYPresentationType.DEACTIVATED -> {
// Nothing to display
}
PLYPresentationType.CLIENT -> {
val paywallId = presentation.id
val planIds = presentation.plans
// Display your own Screen
}
else -> {
//No Screen, it means an error was triggered
}
}
}
try {
// Fetch presentation to display
const presentation = await Purchasely.fetchPresentation({
placementId: 'onboarding'
})
if(presentation.type == PLYPresentationType.DEACTIVATED) {
// No Screen to display
return
}
if(presentation.type == PLYPresentationType.CLIENT) {
// Display my own Screen
return
}
//Display Purchasely Screen
const result = await Purchasely.presentPresentation({
presentation: presentation
})
switch (result.result) {
case ProductResult.PRODUCT_RESULT_PURCHASED:
case ProductResult.PRODUCT_RESULT_RESTORED:
if (result.plan != null) {
console.log('User purchased ' + result.plan.name);
}
break;
case ProductResult.PRODUCT_RESULT_CANCELLED:
console.log('User cancelled');
break;
}
} catch (e) {
console.error(e);
}
try {
var presentation = await Purchasely.fetchPresentation("ONBOARDING");
if (presentation == null) {
print("No presentation found");
return;
}
if (presentation.type == PLYPresentationType.deactivated) {
// No Screen to display
return;
}
if (presentation.type == PLYPresentationType.client) {
// Display my own Screen
return;
}
//Display Purchasely Screen
var presentResult = await Purchasely.presentPresentation(presentation,
isFullscreen: false);
switch (presentResult.result) {
case PLYPurchaseResult.cancelled:
{
print("User cancelled purchased");
}
break;
case PLYPurchaseResult.purchased:
{
print("User purchased ${presentResult.plan?.name}");
}
break;
case PLYPurchaseResult.restored:
{
print("User restored ${presentResult.plan?.name}");
}
break;
}
} catch (e) {
print(e);
}
private PurchaselyRuntime.Purchasely _purchasely;
...
_purchasely.FetchPresentation("presentationId",
OnFetchPresentationSuccess,
Log,
"contentId");
...
private void OnFetchPresentationSuccess(Presentation presentation)
{
Log("Fetch Presentation Success.");
LogPresentation(presentation);
switch (presentation.presentationType)
{
case PresentationType.Normal:
case PresentationType.Fallback:
_purchasely.PresentContentForPresentation(
presentation,
OnPresentationResult,
OnPresentationContentLoaded,
OnPresentationContentClosed,
true
);
break;
case PresentationType.Unknown:
case PresentationType.Deactivated:
Log($"Fetched presentation with type: {presentation.presentationType}. Will not show content.");
break;
case PresentationType.Client:
paywall.Show(presentation);
break;
}
}
Updated 2 months ago