Skip to main content
To get a better understanding of how paywalls are served, visit here.
Migrating from v3? View the migration guide.

Present a Paywall

Install the Helium SDK

Helium requires a minimum deployment target of iOS 15 and Xcode 14+. (Using the latest Xcode is recommended.)
We recommend using Swift Package Manager (SPM) but also offer a Cocoapod.
  1. In Xcode, navigate to your project’s Package Dependencies: Spm Add Pn
  2. Click the + button and search for the Helium package URL:
    For Dependency Rule we recommend the default Up to Next Major Version to make sure you get non-breaking bug fixes. View the list of releases here.
  3. Click Add Package.
  4. In the dialog that appears, make sure to add the Helium product to your app’s main target: Spm Target Pn
  5. Select Add Package in the dialog and Helium should now be ready for import.

Initialize Helium

Initialize the Helium SDK as early as possible in your app’s lifecycle.
Find your API key here. If you do not have a Helium account set up yet, you can still integrate but will not be able to show a real paywall.
Choose the appropriate location based on your app’s architecture:
And import Helium in the same file:

Show Your First Paywall 🎉

Set up a trigger and workflow in the dashboard to show your desired paywall. Create unique triggers for each location a paywall can show in your app! This provides more flexibility with paywall variation and experiments, allowing you to take full advantage of Helium.
Call presentPaywall wherever you want to show a full-screen paywall:
Helium.shared.presentPaywall
method
You should now be able to see Helium paywalls in your app! Well done! 🎉
Looking for alternative presentation methods? Check out the guide on Ways to Show a Paywall.

Recommended Setup

Here are some common additional steps that you may want to consider.

Identifying Users

Identifying users is optional but can help with targeting and when forwarding events to external analytics platforms. If you are not sure, you probably do not need to identify your users.
Identify users as early as you can to maximize consistency in metrics and targeting. Ideally right before you call Helium.shared.initialize!
Set a custom user ID
Set custom user traits for targeting and analytics visibility
If you use an appAccountToken for your existing purchases, then we recommend you also share this value with Helium so Helium can apply the appAccountToken to paywall purchases.

Helium Events

Helium dispatches various events during paywall presentation and purchase flow. You can optionally handle these events in your mobile app. You can also configure Helium to forward them to your existing analytics provider.

PaywallEventHandlers

When displaying a paywall you can pass in event handlers to listen for select events:

Global Helium Event Listener

You can also add one or more global event listeners. For example:
Listeners are held weakly to prevent memory leaks. If you don’t maintain a strong reference to your listener, it will be deallocated immediately and no events will fire.

Fallback Paywalls

It is highly recommended that you set up “fallbacks” to handle the rare case when a paywall fails to display. Please follow this guide to do so.
Do this after you have a paywall created that you want to use in production.

Checking Subscription Status & Entitlements

Helium checks entitlements directly through StoreKit and provides helper methods to make this easier. Consider checking entitlements to gate premium features.
If you have a backend server that manages user entitlements, you may have no use for these helpers.
Accessed from Helium.entitlements:hasAny() Checks if the user has purchased any subscription or non-consumable product.hasAnyActiveSubscription() Checks if the user has any active subscription.hasEntitlementForPaywall(trigger: String, considerAssociatedSubscriptions: Bool = false) Checks if the user has entitlements for any product in a specific paywall. Returns nil if paywall configuration hasn’t been downloaded yet.hasActiveEntitlementFor(productId: String) Checks if the user has entitlement to a specific product.hasActiveSubscriptionFor(productId: String) Checks if the user has an active subscription for a specific product.hasActiveSubscriptionFor(subscriptionGroupID: String) Checks if the user has an active subscription in a specific subscription group.purchasedProductIds() Retrieves a list of all product IDs the user currently has access to.activeSubscriptions() Returns detailed information about all active auto-renewing subscriptions.subscriptionStatusFor(productId: String) Gets detailed subscription status for a specific product, including state information like subscribed, expired, or in grace period.subscriptionStatusFor(subscriptionGroupID: String) Gets detailed subscription status for a specific subscription group.
If you want to check entitlement status before presenting a paywall, here are a couple of ways to do so.
For paywalls that are user-initiated (e.g. “Upgrade to Premium”) and onboarding paywalls, checking entitled status is not recommended. Apps usually want to consistently show a paywall for these locations, and users can still “Restore Purchases” as needed.

Advanced

RevenueCat

By default, Helium will handle purchases for you! This section is typically for users who already use RevenueCat in their app.
Helium integrates seamlessly with RevenueCat so you can continue to let RevenueCat handle your purchases and entitlements.

Install HeliumRevenueCat

  1. In Xcode, navigate to your project’s Package Dependencies.
  2. Click the + button and search for the HeliumRevenueCat package URL:
  3. Add the HeliumRevenueCat product to your app’s main target.
The HeliumRevenueCat package includes purchases-ios-spm as a dependency, not purchases-ios and you may encounter build issues if you are using purchases-ios with SPM. (We recommend just switching to purchases-ios-spm).

Configure Helium to use RevenueCat for Purchases

Simply use Helium’s pre-built RevenueCatDelegate to let RevenueCat handle paywall purchases.
If you do not supply revenueCatApiKey, make sure to initialize RevenueCat before creating the RevenueCatDelegate!
It is best to do this configuration before you call Helium.shared.initialize

RevenueCat appUserID

If you ever change the appUserID of a user, keep Helium in sync with:

Custom Purchase Handling

By default, Helium will handle purchases for you! This section is for those who want to implement custom purchase logic.
Want to add some custom behavior but still use the built-in purchase logic? Just subclass StoreKitDelegate or RevenueCatDelegate! (Be sure to make a super call for any overridden methods.)
You can also create a custom delegate and implement your own purchase logic. You can look at our StoreKitDelegate and RevenueCatDelegate in the SDK for examples (also linked below). The HeliumPaywallDelegate is defined as follows:

Additional Features

For the full public API and detailed parameter documentation, see the inline docstrings in the SDK source. Import Helium in your project and use your IDE’s autocomplete or jump-to-definition to explore all available methods and types.
In most cases there is no need to check download status. Helium will display a loading indication if a paywall is presented before download has completed.
You can check the status of the paywall configuration download using the Helium.shared.getDownloadStatus() method. This method returns a value of type HeliumFetchedConfigStatus, which is defined as follows:
You can also simply check if paywalls have been successfully downloaded with Helium.shared.paywallsLoaded().
Retrieve basic information about the paywall for a specific trigger with Helium.shared.getPaywallInfo(trigger: String) which returns:
This method can be used if you want to be certain that a paywall is ready for display before attempting to display.
You can programmatically hide paywalls using:
Reset Helium entirely so you can call initialize again, for example after changing user traits that can affect the paywalls a user might see via targeting.