Thursday, April 4, 2024
HomeiOS DevelopmentConstructing a backend-driven paywall with RevenueCat – Donny Wals

Constructing a backend-driven paywall with RevenueCat – Donny Wals


On of app improvement’s largest downsides (in my view) is that it’s frustratingly laborious for builders to rapidly iterate on an app’s core options because of the App Evaluate course of which might take anyplace between a couple of hours to a couple days.

Because of this course of, builders both must ship their apps with A/B testing in-built in the event that they wish to check a number of variations of a characteristic, they will iterate extra slowly or they will choose to construct a so-called backend-driven UI. A backend-driven UI is a consumer interface that’s drawn by fetching details about the UI from a server, parsing the data, and putting acceptable UI elements on display primarily based on the retrieved knowledge.

One of the essential elements in an app that implements in-app purchases is the paywall. You wish to guarantee that your paywall is introduced on the proper time, and that it presents the very best supply to your consumer in one of the simplest ways. Normally, you’ll wish to iterate in your paywall and experiment with completely different configurations to resolve which paywall converts finest to your app.

On this publish, we’ll discover RevenueCat’s paywall characteristic to see how we will leverage this characteristic to construct a backend-driven, native paywall to your apps.

This publish is a sponsored publish. Its goal is to offer an trustworthy and honest view on RevenueCat. To guarantee that this publish is effective to my readers, all opinions expressed on this publish are my very own.

Understanding what backend-driven is

If you happen to assume {that a} backend-driven UI sounds extremely difficult, that’s as a result of it may be very advanced certainly. The best model of a backend-driven UI is a UI that masses JSON, parses that JSON into mannequin objects, after which your views render the parsed fashions right into a SwiftUI record view.

On this instance, the backend didn’t resolve how your display seems, but it surely did inform your app about what needs to be introduced to the consumer. After all, it is a quite simple instance of a backend-driven UI and it’s normally not what folks imply after they discuss being backend-driven but it surely does reveal the fundamentals of being backend-driven with out being overly advanced.

After we apply the thought of being backend-driven to RevenueCat paywalls, what we’re speaking about is the power for a backend to inform your app precisely which in-app purchases, metadata and UI components needs to be proven to your consumer.

Let’s get began by taking a look at how one can arrange the RevenueCat facet of issues by configuring a paywall and its contents. After that, we’ll see how we will leverage the RevenueCat paywall in an app to indicate our paywall with backend-driven elements.

Establishing RevenueCat for backend pushed paywalls

If you happen to’ve labored with RevenueCat earlier than, you’ll know that RevenueCat fashions your in-app purchases via entitlements, merchandise and choices. Briefly, right here’s what every of those configurations are for:

  • Entitlement An entitlement is what “marks” your consumer as gaining access to a number of options in your app. Having “professional entry” to an app is an instance of an entitlement.
  • Product These map to your in app purchases in App Retailer Join. For instance, you may have a month-to-month, yearly and lifelong subscription enabled to your app. These are three separate merchandise in App Retailer Join however all three can unlock the identical entitlement in RevenueCat.
  • Choices An providing in RevenueCat is a group of merchandise that you just group collectively as a paywall. This lets you experiment with completely different merchandise being provided to your consumer (for instance, you may have an providing that exhibits your month-to-month / yearly subscriptions, one which solely exhibits your lifetime subscription, and one which exhibits all of your merchandise). You’ll be able to programmatically resolve which providing is introduced to a consumer. You’ll be able to even arrange experiments to current completely different presents to your customers as a method of A/B testing your pricing technique.

With a view to implement a backend pushed paywall, you will want to have created your entitlements and merchandise. If you happen to’re simply getting began with RevenueCat, they’ve nice documentation accessible that can assist you get arrange rapidly.

The trick to implementing a backend-driven paywall is in the way you arrange your supply.

RevenueCat permits you to affiliate JSON metadata along with your providing. You’re free to incorporate as a lot metadata as you’d like which implies that you may present a great deal of paywall associated info for a particular supply as metadata.

For instance, whenever you’re presenting your lifetime subscription solely providing, you may want your app to spotlight the options your consumer unlocks together with some optimistic consumer critiques. Once you’re presenting a consumer with the choice to decide on a month-to-month vs. yearly subscription, you possibly can choose to current the consumer with some advantages of selecting yearly as a substitute of month-to-month.

You would possibly wish to change issues up after you’ve tried an strategy for some time.

All of that is doable by associating the proper metadata to your providing. Within the subsequent part, I’ll present you what this seems like from an app perspective. For now, we’ll give attention to the considerably extra summary JSON facet of issues.

Relatively than displaying you all the pieces that’s doable with this JSON, I’d prefer to give attention to presenting one thing comparatively easy. If you wish to see a extra elaborate instance of what might be performed, take a look at this discuss from RevenueCat’s Charlie Chapman the place he demoes backend-driven paywalls in addition to the corresponding demo app code.

For the needs of this weblog publish, right here’s the JSON I’ll be working with:

{
  "default_selection": "$rc_annual",
  "header": {
    "description": "Get the professional model of TinySteps and luxuriate in limitless actions in addition to a handy sharing characteristic.",
    "title": "Go professional at the moment!"
  }
}

All we’re doing right here is organising a easy header object in addition to configuring a default chosen bundle. This can permit us to experiment with pre-selecting a subscription to see whether or not that impacts a consumer’s alternative between yearly and month-to-month subscriptions.

Right here’s what that find yourself trying like in RevenueCat’s UI.

Screenshot 2024-03-26 at 12.09.53.png

Now that we’ve arrange our providing, let’s check out how we will leverage this in our app.

Presenting the paywall in your app

When you’ve included the RevenueCat SDK in your app and also you’ve configured it along with your api key, you can begin implementing your paywall. For this publish, we’ll implement a quite simple paywall that shows our header, lists all completely different subscription sorts that we’ve got accessible, and we pre-select the subscription that we’ve configured in our JSON metadata.

To get began, we should always write out the mannequin that we intend to decode from our JSON Metadata. On this case, we’re working with pretty easy knowledge so our mannequin might be easy too:

struct PaywallInfo: Decodable {
  let defaultSelection: String
  let header: Header
}

extension PaywallInfo {
  struct Header: Decodable {
    let description: String
    let title: String
  }
}

To load PaywallInfo from our metadata, we will fetch our providing from RevenueCat, extract the metadata, after which decode that metadata into our mannequin object.

Right here’s what that would appear like:

enum PaywallLoader {
  static func getPayWallInfo() async -> (PaywallInfo, [Package])? {
    do {
      guard let providing = strive await Purchases.shared.choices().present else {
        return nil
      }

      let knowledge = strive JSONSerialization.knowledge(withJSONObject: providing.metadata)
      let decoder = JSONDecoder()
      decoder.keyDecodingStrategy = .convertFromSnakeCase
      let paywallInfo = strive decoder.decode(PaywallInfo.self, from: knowledge)

      let packages = providing.availablePackages

      return (paywallInfo, packages)
    } catch {
      print("Error: (error)")
      return nil
    }
  }
}

Within the snippet above, you would possibly discover the next strains and marvel what they do:

let knowledge = strive JSONSerialization.knowledge(withJSONObject: providing.metadata)
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let paywallInfo = strive decoder.decode(PaywallInfo.self, from: knowledge)

The metadata JSON that we get on our providing is of sort [String: Any]. We all know that this knowledge originated as JSON from the RevenueCat admin panel however we wish to have the ability to remodel the [String: Any] dictionary into our mannequin object. To do that we convert the dictionary to Information, and from Information into our mannequin. It’s a little bit tedious but it surely works.

As soon as we’ve retrieved our knowledge, we will use it to populate our view.

The next exhibits a particularly bare-bones instance of utilizing our PaywallLoader in a view:

struct PaywallMainView: View {
  @State var paywallData: (PaywallInfo, [Package])?
  @State var selectedPackage: Bundle?

  var physique: some View {
    if let paywallData {
      VStack {
        Textual content(paywallData.0.header.title)
          .font(.title)

        Textual content(paywallData.0.header.description)
          .font(.title)

        ForEach(paywallData.1) { bundle in
          if bundle.identifier == selectedPackage?.identifier {
            Button(bundle.storeProduct.localizedTitle, motion: {
              selectedPackage = bundle
            })
            .background(Shade.grey)
          } else {
            Button(bundle.storeProduct.localizedTitle, motion: {
              selectedPackage = bundle
            })
          }
        }
      }
    } else {
      ProgressView()
        .activity {
          paywallData = await PaywallLoader.getPayWallInfo()
          selectedPackage = paywallData?.1.first(the place: { bundle in
            return bundle.identifier == paywallData?.0.defaultSelection
          })
        }
    }
  }
}

This code is solely supplied as a reference to indicate you what’s subsequent after decoding your mannequin knowledge. It’s not supposed to look fairly, neither is it supposed to indicate you essentially the most lovely paywall. The important thing lesson right here is that you may leverage the JSON metadata on a RevenueCat providing to construct a paywall that makes use of backend-driven UI, permitting you to experiment with completely different texts, configuration and extra.

In Abstract

There’s no restrict to how versatile you will get with a backend-driven UI apart from your creativeness. On this publish, I’ve proven you a really fundamental backend-driven UI that may permit me to alter a default choice for my paywall and to experiment with completely different texts on my paywall.

You’ve seen how one can configure an providing in your RevenueCat console with any JSON you’d like, permitting you to experiment to your coronary heart’s content material. You’ve additionally seen how one can write code that fetches an providing and extract the related info from the JSON metadata.

Once more, there’s nearly no restrict to what you are able to do right here. You’ll be able to present as a lot JSON knowledge as you’d prefer to construct advanced, dynamic, and customizable paywalls that may be up to date on the fly. No App Evaluate wanted.

I’m a giant fan of RevenueCat’s implementation of JSON metadata. With the ability to broaden the accessible info like it is a enormous profit to experimentation and testing to seek out out the best possible paywall implementation to your app.



Supply hyperlink

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments