Superwall: Remote Paywall Configuration on iOS

Subscriptions are a great way to monetize your app. By showing a paywall, you can convert your free users into paying subscribers who help fund that Ferrari you’ve had your eye on. As such, creating a high-converting paywall is extremely important. But accomplishing that’s annoyingly difficult. It typically requires countless hours of iterating on design, messaging, placement, pricing and features to get it just right. Even then, the job is never finished and even the highest-grossing apps still test different paywalls to maximize profits.

Fortunately, Superwall has come to the rescue. It’s created an SDK to let you remotely configure every aspect of your paywall and quickly find the best version.

In this tutorial, you’ll build an app that generates motivational gym quotes behind a paywall that’s remotely configured on Superwall. Along the way, you’ll learn:

  • How to integrate and use Superwall to remotely configure your paywall.
  • What Events, Campaigns and Rules are.
  • How to create an A/B test.
  • How to measure paywall performance.

Getting Started

Download the starter project by clicking the Download Materials button at the top or bottom of the tutorial.

Once downloaded, open GymMotivation.xcodeproj from the starter folder and look around. You’ll find the project provides the interface for a welcome screen and a motivational quote generator.

Build and run. You’ll see a welcome page with a button at the bottom of the screen:

Tap the Get Inspired button to navigate to the motivational gym quote generator:

Motivation Gym Quote Generator

Refresh the quote by tapping the refresh arrow in the top right.

With motivational quotes like these, someone using your app might just become the next Arnold Schwarzenegger. Why give this content away when people could be paying good money for it?

In Xcode, you’ll see a StoreKit testing configuration called Products.storekit containing three auto-renewable subscriptions that each have a week’s free trial. StoreKitService.swift provides some code to help implement in-app subscriptions.

Your task is to add a remotely configured paywall that uses these products to give access to these quotes.

Exploring the Dashboard

Without further ado, sign up for a free account on Superwall’s website.

After signing up and entering your app details, you’ll see the dashboard:

The Superwall dashboard.

This has many uses, including:

  • Creating new paywalls.
  • Analyzing, editing and controlling existing paywalls.
  • Viewing paywall metrics.
  • Defining conditions for when to show paywalls to users.
  • Viewing users and their user journey through your app and paywall.
  • Localizing your paywalls.

In the Paywalls section, you’ll see there’s an example paywall already created for you:

An example paywall in the Superwall dashboard.

This is a useful starting point. Click the Example Paywall and you’ll see an interface with preconfigured data:

The paywall editor

The left-hand side splits into two tabs: general and layout.

General Tab

In this tab you configure the following:

You can specify up to three products for your paywall. In your app, the SDK will pull real, localized product data from the App Store based on your product ids. However, in the editor, Superwall will use example product data that you provide as a preview. If your app is on the App Store, Superwall will extract its bundle identifier and pre-fill product values when you create a product on Superwall. If you’re using RevenueCat to handle your in-app subscriptions, you can set your RevenueCat API key here or in settings. It’ll automatically load your product identifiers from any product attached to an offering. Alternatively, you can manually fill in product data.


These settings determine how the paywall displays and how it behaves.

Fonts, Sizing, Spacing, Colors and Advanced

Here you alter global design settings of the paywall.

Layout Tab

Click the Layout tab in the top left. You’ll see a basic overview of the structure of the paywall:

The Layout tab of the Paywall Editor.

You use this tab if you want to change the layout of your paywall design by adding/removing elements. This is an incredibly powerful feature that allows you to construct any paywall design you want.

Have a play around by clicking and dragging some elements and see how it changes the layout of the paywall preview in the center of the page. Any changes you make save locally but are not published until you hit the Save button. When you’re ready to continue, click Unpublished, and click Revert to go back to the original paywall design.

Paywall Preview Section

In the center of the page you’ll see the interactive paywall preview with selectors at the top to change the localization and the device type:

The paywall preview section

Mouse-over the title element on the paywall and you’ll see a blue border appear around it:

A highlighted element on a paywall.

All elements on the paywall are configurable. Click the title element and you’ll see a configuration interface appear in the right-hand sidebar.

Paywall element configuration sidebar.

Element Configuration Section

By switching between the Default and the Free Trial tab at the top, you can switch between the configuration of the element when there’s a free trial available vs when there isn’t. The SDK chooses the element’s free trial state when it detects a free trial in any of the products on the paywall and the user hasn’t already used a free trial within that product’s subscription group.

The free trial configuration inherits from the default configuration.

With text elements like this, you can insert variables. These reference product data, user properties and device properties that the SDK subtitutes. Click + Add Variable to see a list of everything you can add:

Variables that you can add to your text elements.

AI Powered Suggestions

This section gives you intelligent alternative suggestions for your text element powered by OpenAI’s GPT-3. If you’re running out of ideas with your paywall copy, then this is your friend!

Click Behavior

You can choose what happens when someone clicks on an element. This includes: opening URLs, deep links, closing the paywall, restoring, purchasing, or custom actions.

The rest of the sidebar focuses on customizing the design of the element.

You’ve now got a feel for how to configure a paywall on the dashboard.

Understanding Campaigns

How do you determine when to show configured paywalls to users? And to which group of users? That’s where Campaigns come in.

A campaign allows you to define conditions for when to show paywalls to users. They tie together three concepts:

  1. Events: Analytical events you register in your app.
  2. Rules: Logic that determines when to show a paywall.
  3. Paywalls.

You can think of a campaign as follows: When registering these events, evaluate these rules and show these paywalls.

Head back to the dashboard and scroll down to the section named Campaigns and click Example Campaign:

The Campaigns section


At the top of the page is where you add your events. In this campaign, there’s already one there called campaign_trigger:

Events for the Example Campaign

Later on, your app will register this event via the SDK. You can name an event almost anything you like.

Superwall automatically tracks events and some of these can present paywalls. Specifically:

  • app_install: On configuration of the SDK for the first time.
  • app_launch: On app launch from a cold start.
  • session_start: On app open either from a cold start or after at least 30 seconds since the app left the foreground.
  • deepLink_open: When opening a deep link in the app.
  • transaction_fail: When a transaction fails.
  • transaction_abandon: When a user abandons a transaction.
  • paywall_decline: When a user declines a paywall.


Further down the page you’ll see a rule set to true:

A campaign rule

As this is true, all users will match the rule. Click the rule to bring up the Rule Editor:

The Rule Editor

Using this, you can create more complex rules by filtering by user, device and event parameters provided via the SDK. You can also add a limit to how often they should match.

Rules get evaluated in order and once a user matches a rule, no other rules get evaluated. If a user doesn’t match a rule, they aren’t shown a paywall.

Here are some example rules you could use:

  • if user.days_logged >= 3 then, show 6 times every 2 weeks.
  • user.genre == "jazz" or user.genre == "classical"
  • params.outcome contains "substring"


Underneath each rule is a group of paywalls. You’ll see one paywall assigned to 100% of users. In fact, that’s the example paywall that you saw earlier:

A group of paywalls that belong to a rule.

Underneath each paywall title is the amount of users currently assigned to that paywall. Paywalls assignments are sticky, which means users will always see the same paywall assigned to them for a given rule. An arrow appears next to it which you can click if you’d like to reset the assignment for those users:

Amount of people assigned to a paywall

If you wanted to, you could add multiple paywalls to this rule and assign each paywall to a certain percentage of users. If instead of 100% of users, you assigned only 50% of users to the paywall, the remaining 50% wouldn’t see a paywall, meaning they are in a holdout group. All these features make it possible to run A/B tests to determine the most effective paywall, which you’ll do later on.

This above is a very simple set up, however, advanced setups are possible. Check out the Superwall docs for more info.

You’ve now got a feel for how the dashboard works. The next step is to integrate the SDK into your app and trigger your first paywall!

Integrating the Superwall SDK

Adding the Superwall iOS SDK

To show the paywall in your app, you first need to add the Superwall iOS SDK called SuperwallKit to your project as a Swift Package.

In Xcode, select File ▸ Add Packages…, then paste the SuperwallKit package URL into the search bar.

Set the Dependency Rule to Up To Next Major Version and specify 3.0.0 as the lower bound. Then, click Add Package:

Adding the Superwall Swift package

Initializing the SDK

Next, you need to initialize the SDK when the app launches. Open AppMain.swift and add the following to the top of the file:

import SuperwallKit

Then, add the following to configure Superwall on init():

init() {
  Superwall.configure(apiKey: "YOUR_API_KEY")

Open the Superwall dashboard, click the Settings tab in the sidebar, select Keys and copy the Public API Key:

Back in AppMain.swift, replace YOUR_API_KEY with your Public API key.

Build and run your app. You won’t notice any visual changes. But if you head to the Superwall dashboard, you’ll notice the first two items checked off in the quickstart checklist. You’ve successfully configured the Superwall SDK:

Completion of two items on the onboarding checklist

Presenting the Paywall

The ideal place to show the paywall in your app is when the user presses the Get Inspired button. When that happens, you’ll need to register the event campaign_trigger.

At the heart of Superwall is register(event:params:handler:feature). This allows you to register an event to access a feature that may or may not be behind a paywall later in time. It also allows you to choose whether the user can access the feature even if they don’t make a purchase.

It takes the following parameters:

  • event: The name of the event you wish to register.
  • params: Optional parameters that you can refer to in your paywall and the rules you define in your campaign.
  • handler: An optional handler whose functions provide status updates for a paywall.
  • feature: An optional completion block containing a feature that you wish to put behind a paywall.

The calling of the feature block depends on whether the paywall is gated or non-gated:

  • Gated: Only calls the feature block if the user is already paying or if they begin paying.
  • Non-Gated: Calls the feature block when the paywall dismisses regardless of whether they paid or not.Gating is remotely configurable in the paywall editor.It’s recommended to register all core functionality in your app in order to remotely configure which features you want to gate without an app update.

    Adding Register to Your App

    Open WelcomeView.swift. In continueButton(), replace:



    Superwall.shared.register(event: "campaign_trigger") {

    That’s all you need!

    Build and run your app. Tap the Get Inspired button and see your paywall presented!

    A presented paywall.

    Head to the dashboard and you’ll see the next few steps checked off in the onboarding list:
    Three elements in onboarding list checked off.

    You now have working logic in your app to show a paywall. Unfortunately, it still very much looks like a template and the Purchase Primary button to purchase products doesn’t work!

    Close the paywall by tapping the right button in the top right of the paywall. You’ll notice it navigates straight to your precious quotes after the paywall closes. That’s because the paywall is non-gated and therefore activates the feature block even though you haven’t paid. For your app, you need to make this gated. Ain’t nobody getting free quotes!

    Customizing Your Paywall

Making Your Paywall Gated

Open the Paywall Editor for the Example Paywall on the Superwall dashboard.

In the General tab, scroll down to Settings and change Feature Gating to Gated:

Changing the feature gating

Click the Save button in the top right.

Now build and run your app. Tap the Get Inspired button to launch your paywall and then close it again by tapping on the right button in the top right. When the paywall closes, it won’t navigate to your quotes!

Adding Products to Your Paywall

Back in the Paywall Editor, create your first product by clicking the + Create Product button in the Products section:

The create product button

In the popup, set the Product Identifier to gm_2099_1y, Trial to 1 week, Price to 20.99 and Period to Year:

Adding a product.

Save the paywall, then build and run your app.

Present the paywall and tap the Purchase Primary button. You’ll see it presents the purchase sheet for you to purchase the product:

Purchasing a product.

Tap Subscribe and purchase the product. After purchasing the paywall will dismiss and you’ll navigate through to the MotivationView. Delete the app to reset your subscription status for the purposes of this tutorial.

This is now a fully functioning paywall! Open the Superwall dashboard to confirm all onboarding steps checked off:

All onboarding items checked off

All that’s left is to alter the paywall’s design to be better suited for your app.

Adjusting Paywall Design

Open the Paywall Editor and click the Layout tab.

For simplicity’s sake, we’ll only keep a few sections and delete the others that we don’t want. In a production-ready paywall, you’ll want to experiment with the length of your paywall. Usually, longer paywalls perform better. This is because purchasing is an emotional decision so you’ll want to give your users enough information to persuade them that your product is deserving of a small portion of their children’s inheritance.

Click the trash can icon next to the Section element underneath the Subheading element in the Main Content list:

Deleting a section

Click Delete in the popup that appears. Repeat these steps and delete the next two Sections underneath Subheading. Finally, scroll down and delete the very last Section in the Main Content list. You should end up with 4 sections and a navbar:

The first part of the updated paywall.

The second part of the updated paywall.

In the navbar, click the left button, and set its Display to None:

Hiding the left button.

Repeat this for the Title navbar element. Set the text of the right button to Exit.

Select the image element and click the Upload button. Choose the image named paywall-image.png from your tutorial materials. Then change Top Padding to 40px:

Uploading an image

Replace the main heading text with:

Unlock Pro

Replace its subtitle text with:

with a {{ primary.trialPeriodText }} free trial

This references the trial period of your primary product within the text.

Set the bullet points’ heading’s Display to None. Then for each bullet point title, hide it’s subtext in the same way.

Replace each bullet point text such that your list looks like this:

  • Unlimited quotes
  • Unlimited motivation
  • Maximum amount of gains
  • Cancel anytime in seconds

Then replace the title above the review section with:

Highly rated

For the purchase button, replace the text with Continue in its default state and Try now in its free trial state.

Replace the primary selected description with:

Only {{ primary.price }} per {{ primary.period }}

Click the Save button, then build and run your app to see your new paywall in action! It should look like this:

A screenshot of an edited paywall

A screenshot of an edited paywall

Testing Paywall Variants

Say you’ve launched your app on the App Store but have a feeling the title isn’t really selling the product. You’d like to test a paywall with different copy and see if it makes more sales. With Superwall, you can run multiple paywalls at the same time.

Open the Superwall dashboard. Under Paywalls, hover over your paywall’s name and click copy:

The paywall copy button

Click Duplicate to redirect to the paywall editor for the duplicate paywall.

Click the title in the paywall Unlock Pro and replace it with:

Unlock your full potential. Go Pro.

Then, click the title of the paywall to change it from Example Paywall (copy) to:

Example Paywall | Title Change

Click Save and head back to the dashboard. Under Campaigns, click Example Campaign and add a new paywall variant to your rule by clicking + Add Paywall:

Adding a new paywall variant

Select your paywall Example Paywall | Title Change from the drop down and click Create:

Choosing a paywall variant.

Then, above your newly added paywall, click 0% of users, set both paywall values to 50 and click the check mark to confirm your new traffic distribution:

Adjusting paywall traffic

You now have an A/B test running two paywalls at the same time, with a 50/50 traffic split between them. Your original paywall is the control and the new one is a variation or variant.

Analyzing Paywall Performance

How do you know which is the winning paywall in an A/B test? What should you do after you have a clear winner? What performance indicators should you measure? All very important questions!

After data starts coming in for your paywalls, you can view metrics underneath each campaign rule like this:

A table of data below a rule.

These default to data retrieved in the last 24 hours but you can change this to any time range in the top right corner of the campaign page:

Dropdown to change the date for campaign metrics.

You can use this data to analyze your paywalls’ performance.

A company called CXL have created a calculator that will help you take your results from Superwall and figure out whether they are statistically significant. Open their calculator:

AB+ Test Calculator by CXL

As an example, let’s say you’ve been running a test with the above paywalls for 30 days. In the campaign, you’ve seen that there have been 300 opens for each paywall since you set up the test. It turns out you’ve had 20 conversions, or purchases, from the control and 40 conversions from the variation. All you need to do is input this data into the AB+ Test Calculator.

In the Test duration input field, enter 30.

On the AB+ test calculator website, input 300 in the Users or sessions fields for both the control and variation. Then input 20 and 40 in the Conversions fields for the control and the variation respectively.

The AB+ Test Calculator filled out with example data.

If you had more paywall variations you could add another by clicking Add Variant. Leave Step 3 of the calculator as it is. This is where you’d adjust the confidence level of your experiment if you wanted to:

Step 3 in the AB+ Test Calculator.

Finally, the results will be automatically calculated for you using Bayesian statistics. This answers the question “How likely is it that the variation(s) will be better than the control?”, or vice versa. It outputs two graphs. The first gives the probability of each paywall variation being the winner and the second indicates the probability of a paywall’s conversion rate:

Graphs showing the probability of each paywall variation being the winner and the likelihood of a paywall's conversion rate.

As you can see, the variation has a 100% chance of being the winner compared to the control.

Open the campaign on the Superwall dashboard and remove the losing paywall by clicking the x in the corner:

Removing a paywall variant from a campaign.

Confirm the removal of the paywall:

Confirming the removal of a paywall variant

This will make it reset the paywall assignment for users assigned to that paywall. Then, set 100% of traffic to the new paywall:

Setting 100% of traffic to a paywall.

Given the example data above, you can see that you’ve doubled your income just from running an experiment. But it’s not over! After this, you’d want to try a new experiment such as changing the positioning, design, or pricing of the paywall.

Where to Go From Here?

You can download the complete project by clicking the Download Materials button at the top or bottom of this tutorial.

This project scraped the surface of what you can do with Superwall. There’s still plenty to learn, including:

  • Identifying users.
  • Assigning user properties.
  • In-app paywall previews.
  • Localizing paywalls.
  • Game controller support.
  • 3rd-party analytics.
  • Custom paywall buttons.
  • Custom paywall presentation
  • Using deeplinks to show paywalls

If you want to learn more about Superwall’s capabilities, check out its documentation.

To learn more about configuring in-app subscriptions, check out In-App Purchase Tutorial: Auto Renewable Subscriptions.

I hope you enjoyed this tutorial. If you have any questions or comments, join the discussion below.

Source link

Leave a Reply

Your email address will not be published. Required fields are marked *