Displaying Products

Configure Products

Before working with products in SDK, make sure you created all in-app purchases in App Store Connect / Google Play Console, and made necessary set up in Aphud Product Hub. Please follow our Configuring Products guide for details.

Placements (New Feature)

Apphud introduces a new and recommended approach for managing your app's paywalls: Placements.

Placements offer a strategic method to integrate paywalls throughout your app. This feature allows app developers to position paywalls effectively in different app sections, such as onboarding, settings, etc., with each placement targeting a distinct user audience. For more comprehensive information, please refer to our Placements guide.

To utilize a paywall, first retrieve the corresponding placement. Once you have a specific placement object, you can access its associated paywall and the products:

Task {
	let onboardingPlacement = await Apphud.placement(ApphudPlacementID.onboarding.rawValue)
  if let paywall = onboardingPlacement?.paywall {
		let apphudProducts = paywall.products
	  Apphud.paywallShown(paywall)
		// setup your UI with these products
  }
}
Apphud.placementsDidLoadCallback { placements in
    // if placements are already loaded, callback will be invoked immediately
    if let placement = placements.first(where: { $0.identifier == "your_placement_id" }), let paywall = placement.paywall  {
        let products = paywall.products
      	Apphud.paywallShown(paywall)
        // setup your UI with these products
    }
}
val placements = Apphud.placements()

🚧

Access Paywalls Correctly

It's crucial to retrieve paywalls correctly based on your chosen feature. If your app uses the Placements feature, you must obtain the paywall object directly from the corresponding placement object. Avoid using the standalone paywalls array from the SDK in this context. Fetching a paywall through Apphud.paywalls() in a placement-based setup will disrupt your analytics, as purchases won't be accurately attributed to the respective placement.

Paywalls

Paywall structure allows you to operate with your products array remotely as well as run A/B experiments on them. You can read more in our Paywalls guide.
Technically, each ApphudPaywall contains array of ApphudProduct objects, paywall identifier, JSON dictionary, and a few other properties.

📘

Manage A/B experimented paywalls

See more details about paywalls logic regarding A/B experiments

Using Paywalls Directly (Deprecated)

You can still work with paywalls array directly by calling:

Task {
  if let paywall = await Apphud.paywall(ApphudPaywallID.onboarding.rawValue) {
		let apphudProducts = paywall.products
	  Apphud.paywallShown(paywall)
		// setup your UI with these products
  }
}
Apphud.paywallsDidLoadCallback { paywalls in
    // if paywalls are already loaded, callback will be invoked immediately
    if let paywall = paywalls.first(where: { $0.identifier == "your_paywall_id" }) {
        let products = paywall.products
      	Apphud.paywallShown(paywall)
        // setup your UI with these products
    }
}
[Apphud paywallsDidLoadCallback:^(NSArray<ApphudPaywall *> * _Nonnull paywalls) { 
[Apphud paywallShown:paywall];
}];
val paywalls = Apphud.paywalls()
ApphudSdk.paywallsDidLoadCallback().then((paywalls) => {
   // todo
})

In a callback you can fetch your paywall by identifier. You must provide paywall identifier when adding new paywall in Apphud Product Hub. Here are typical paywall identifier names that you can use: "main", "onboarding", "settings", "over_limit", etc.
Best practice is to have one paywall identifier per view/controller. However, at certain scenarios you may have different paywall identifiers per same class.

❗️

If products are missing in the response

In case of App Store or Google Play products are missing in the paywalls structures, check out App Store and Google Play products setup checklists.

Log Paywall Shown

Logging Paywall Shown event is highly recommended, as it influences the calculation of 'Affected Users' and major Paywall Conversion Rates metrics, which are key components in Paywall Analytics, Placement Analytics, and A/B Experiments.

Apphud.paywallShown(paywall)

🚧

Do not duplicate

Please make sure that this method is called just one time per payment screen shown.

Get Native Product Model

Apphud automatically fetches SKProduct / Product /ProductDetails objects upon launch and populates them in paywalls.

To operate with native product model, retrieve it from ApphudProduct wrapper object:

// fetch Product from ApphudProduct object, returns immediately, if available.
let product = await apphudProduct.product()
// returns skProduct object wrapped in ApphudProduct object
apphudProduct?.skProduct
[apphudProduct skProduct];
// returns productDetails object wrapped in ApphudProduct object
apphudProduct?.productDetails

Fetching Native Products the Old Way

If you don't want to use paywalls, you can still operate with native products array:

let products = try await Apphud.fetchProducts()
// returns nil, if products are not yet loaded from the App Store
Apphud.fetchProducts { products, error in }
[Apphud products];
// returns null, if products are not yet loaded from Google Play
Apphud.products()
await Apphud.products();
await ApphudSdk.products();

Additional Resources:


What’s Next