Monetizing a SwiftUI App: IAP & Subscriptions

April 12, 2022
Dan Burcaw
Nami SwiftUI paywall
Photo by

We decided it was time to build and ship a brand new app using SwiftUI to experience first hand the latest from Apple.

The app, now available on the App Store, is called Serenity Now.

It’s a simple audio player with a SwiftUI interface and AVFoundation under the hood. The app is filled with a collection of sounds for focus, relaxation, and better sleep.

App Monetization Goals

We’re in the monetization business, so we set out to implement our own Nami SDK to offer IAPs and subscriptions.

Here are the three products we want to offer:

  • Lifetime Access - $49.99 for life (only available as a launch exclusive)
  • Monthly Subscription - 3 day free trial, then $3.99 / month
  • Yearly Subscription - 1 month free trial, then $39.99 / year

Users who buy one of these products gets access to our Serenity Now Premium features. Those features include:

  • Premium-only sound collections - Nature, Uplifting, Water & Sleep
  • Premium controls - Repeat & AirPlay
  • Ad-free experience

We want users to encounter our paywall during the app experience in three different places:

  • First Launch - The first time the user launch the app
  • Gated Content - Upon tapping a content tile that requires premium access
  • Marketing Tile - Tapping the premium access marketing tile in Settings

Now that our goals are clear, let’s see what it takes to accomplish.

The SwiftUI Lifecycle & SDK Initialization

SwiftUI apps don’t use the the AppDelegate we have all come to know from years of building iOS apps. Instead, the entry point for SwiftUI apps is a struct conforming to the App protocol.

That protocol has one requirement, which is the implementation of a property called body. Digging into the specifics of body is outside the scope of this article, but suffice it to say that is where you’ll kick off your app’s user interface.

For our purposes, we need a place to configure the Nami SDK. It turns out, we can provide a custom init() method on our App struct for this purpose.

Here we setup our NamiConfiguration object with our app’s unique appPlatformID (found in the Nami Control Center > Integrations > [your Apple App Store integration]

Setting up an ObservableObject to Track Purchase State

We will need to monitor changes to the the entitlements a user has access to. A change may occur if they buy one of our IAP products, or if they have a subscription that expires.

In Serenity Now, if a user buys any one of the three IAP products, we grant them access to an entitlement called premium_access.

In SwiftUI, we can monitor for user entitlement changes by setting up an ObservableObject. Specifically, we need to register with the Nami SDK’s registerEntitlementsChangedHandler callback to update our ObservableObject’s premium var.

Since premium has a @Published property wrapper, any SwiftUI view’s body will be re-invoked any time the value changes.

This is exactly what we want. If a user buys one of our products, we want any of the SwiftUI views that rely on the value of premium, to be updated. Concretely, this means any view that gates access based upon the premium_access entitlement will update if the value changes.

Paywall Use Case: Initial App Launch

Next, we want to show our paywall the first time the user launches the app.

Serenity Now app paywall

In our main SwiftUI view, SerenityNowHome, we run some code in .onAppear that checks UserDefaults for the value of a key didLaunchBefore. If the value is false, it’s the first launch of our app so we tell the Nami SDK to show a paywall if NamiDataSource’s premium var is False.

Paywall Use Case: Gating Premium Content

Next, we want to gate access to certain premium content in our app.

Gating premium access with Nami

If the user does not have access to the premium content (e.g. NamiDataSource’s premium var is False), we want to present the paywall. Otherwise, we want to show the SwiftUI with the relevant content.

Paywall Use Case: Premium Marketing Tile

Finally, we want to give users a way to access our paywall from a marketing tile in the Settings section of our app.

Providing a premium upsell banner in SwiftUI

In our Settings view, if the user does not have premium access (via our NamiDataSource), we show our NamiUpsellBannerView. If the user taps on it, we show our paywall.

If the user does have premium access, we instead show a link to Manage subscription which takes the user to the system Settings.

Final Thoughts

There is much more we want to do with our SwiftUI app and some advanced use cases we want to discuss in future blog posts. For now, we hope this article shows how is it is to get up and running with some very common use cases for selling IAPs and subscriptions.

You may be wondering about the paywall view itself. The paywall was created via Nami’s no-code paywall designer. The Nami SDK provides a native Swift that is configurable from the Nami Control Center so you can make changes instantly.

The SDK provided paywall integrates seamlessly with our SwiftUI app from both a user interface and usability perspective. If you’re interested in giving Nami a spin for your own SwiftUI app, you can create a free account here.

Sign up to our newsletter

Get the latest articles delivered straight to your inbox.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Nami® logo

Focus on your app experience

We'll handle the subscriptions.

Nami® logo

Maximize your App's Potential

Accelerate app revenue with Nami subscriptions.

Portrait photo of blog author
Dan Burcaw

Dan Burcaw is Co-Founder & CEO of Nami ML. He built a top mobile app development agency responsible for some of the most elite apps on the App Store and then found himself inside the mobile marketing industry after selling his last company to Oracle.

Similar articles

Read similar articles to this one

Quotes mark


Some client stories

"We spent hours researching the best ways to implement subscriptions and after many failed attempts we found Nami. We were able to go live with subscriptions in our Apple and Android apps in a matter of days."
Client portrait
Brian Pedone
Quiet Punch
Quiet Punch
"Nami helped us achieve a cross-platform solution for managing and sellingsubscriptions on Apple and Google. The Nami platform was flexible enough to handleour business requirements for in-app purchasing, allowing us to focus on our client'score domain and domain logic.”
Client Name
Client role
Company name
"Nami helped us achieve a cross-platform solution for managing and selling subscriptions on Apple and Google. The Nami platform was flexible enough to handle our business requirements for in-app purchasing, allowing us to focus on our client's core domain and domain logic."
Melody Morgan
Director, Engineering
"We spent hours researching the best ways to implement subscriptions and after many failed attempts we found Nami. We were able to go live with subscriptions in our Apple and Android apps in a matter of days."
Brian Pedone
Quiet Punch
Quiet Punch
"It took a couple of hours to incorporate their easy to use SDK. Nami provides a monetization machine learning solution, a paywall displaying what a user can purchase, and a whole suite of other useful features. As a result, it saved me development cycles so I could focus on other important things."
Mark Lapasa
Android Developer
Toronto App Factory
Toronto App Factory
"After spending a few days trying to implement subscriptions, I found Nami ML. I was able to complete in-app subscriptions within less than 3 hours."
Tanin Rojanapiansatith
iOS Developer

The best subscription experience starts with Nami

Get connected with one of our product experts to get started with your journey with Nami today.