How to add a paywall with a single line of SwiftUI code 🛍️

Have you ever thought of integrating in-app purchases into your app, but ended up not doing it because the task felt too complex?

I have a really good news for you: since iOS 17 Apple has made it so easy that you can literally integrate in-app purchases with a single line of code!

And in this article I want to show you how it works and just how far you can go with this built-in integration!


This content has been written in commercial collaboration with RevenueCat.

However the approach I describe will work with any iOS app, regardless of whether or not it uses RevenueCat đź‘Ť


If you’ve ever tried to add a paywall to your app, you know how strict Apple can be on what you’re allowed to show or not on that screen.

Everything must be crystal clear so that users don’t feel cheated when their payment methods are being charged.

But while these rules are really beneficial to create trust with users, they also lead to some back-and-forth with the app review team the first time that a developer adds a paywall to their app.

And, of course, such back-and-forth will consume a lot of time and energy on the developer’s end…

Or rather, that’s how things used to be until iOS 17!

Because in iOS 17, Apple decided to create built-in SwiftUI views that literally display fully functioning paywalls through a single line of code!

First, let’s add a StoreKit configuration file to our app, to simulate an in-app subscription: a Pro tier with monthly or yearly durations:

(if you’re not familiar with how StoreKit configuration files work, I’ve covered this topic in details in a previous article)

Now that our app contains in-app purchases, let’s add a paywall so that users can actually purchase them:

And believe or not, just by adding this SubscriptionStoreView, we’ve gotten ourselves a fully functioning paywall!

Of course for now its design is very very rough!

But look at all that we’ve gotten with almost no effort:

  • all of the copy required to explain the pricing is there

  • users can select and purchase a subscription

The paywall even updates once a purchase has been made to highlight which plan the user is subscribing to and to allow them to switch to the other if they want!


This paywall does have one limitation though: it can only display in-app purchases that belong to the same subscription group.

This means that you wouldn’t be able to also display a non-recurring option, like a lifetime purchase.

If you need to implement this use case, check out the end of this article, because RevenueCat does have a nice solution for that!


And from there, we can totally add more code to configure how our paywall looks and behaves.

For instance, we can replace the default header with a custom view:

We can also add a button so that users can easily attempt to restore a previous purchase:

And if we want to create a funnel in our analytics to measure the performance of our paywall, we can also do it by providing closures that will be called when a user starts and completes a purchase:

Even better, imagine that you update your in-app subscription to include a free trial period:

Then we don't need to make any change to our code: our SubscriptionStoreView will automatically adapt its copy to reflect that the yearly plan now offers a free trial period:


Believe it or not, in this article we’ve only scratched the surface of what SwiftUI’s built-in StoreKit views can do!

here’s an example of what a SubscriptionStoreView can look like with a just a bit more code to customize its appearance

If you want to learn more, I recommend reading the documentation or watching the WWDC session Meet StoreKit for SwiftUI.

And if you want to take your paywall even further without spending too much time and energy on it or if you need to support iOS < 17, I recommend that you check out RevenueCat Paywalls.

RevenueCat Paywalls offer a large choice of built-in paywalls, along with powerful capabilities such as updating the paywall without an app update or running A/B tests with different paywalls.

Even better, RevenueCat Paywalls lift one of the shortcomings of SubscriptionStoreView: they allow you to show both a non-recurring purchase (like a lifetime option) and a recurring purchase on the same paywall đź‘Ś

Once again, I have a big thank you to RevenueCat for sponsoring this article!

Next
Next

Bad practice creating a StateObject