Skip to content

Instantly share code, notes, and snippets.

@codykerns
Created November 25, 2024 15:31
Show Gist options
  • Select an option

  • Save codykerns/bd385073cdca852310f30e560e1b7cc0 to your computer and use it in GitHub Desktop.

Select an option

Save codykerns/bd385073cdca852310f30e560e1b7cc0 to your computer and use it in GitHub Desktop.
Display a different RevenueCat paywall based on current size class in SwiftUI
//
// OfferingDecider.swift
//
// Created by Cody Kerns on 11/25/24.
//
import Foundation
import SwiftUI
import RevenueCat
import RevenueCatUI
/// In the RevenueCat dashboard, add an Offering Metadata key for an alternative offering identifier to present if the size class isn't compact
/// e.g.
/// {
/// "alternative_offering_id": "my_other_offering_identifier"
/// }
struct OfferingDecider {
static func getOffering(for sizeClass: UserInterfaceSizeClass?) async -> Offering? {
do {
let offerings: Offerings = try await Purchases.shared.offerings()
// if there isn't an offering configured, return nil
guard let currentOffering = offerings.current else { return nil }
// if the size class is compact, return the standard offering
guard sizeClass == .regular else { return offerings.current }
if let alternativeOfferingId = currentOffering.metadata["alternative_offering_id"] as? String {
// if there's an alt offering id set in metadata, return the offering with that id
// if it's nil, return the current offering
return offerings.all[alternativeOfferingId] ?? currentOffering
} else {
// no alternative id set, just return the current offering
return currentOffering
}
} catch let err {
print("Error fetching offerings: \(err)")
return nil
}
}
}
class ExampleViewModel: ObservableObject {
@State
var shouldDisplayPaywall = false
var paywallOffering: Offering? = nil
func displayPaywall(for sizeClass: UserInterfaceSizeClass? = nil) {
Task {
if let offering = await OfferingDecider.getOffering(for: sizeClass) {
paywallOffering = offering
shouldDisplayPaywall = true
}
}
}
}
struct ExampleView: View {
@StateObject var viewModel: ExampleViewModel
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
var body: some View {
List {
Button("Show Paywall") {
viewModel.displayPaywall(for: horizontalSizeClass)
}
}
.sheet(isPresented: $viewModel.shouldDisplayPaywall) {
if let paywallOffering = viewModel.paywallOffering {
PaywallView(offering: paywallOffering)
} else {
PaywallView()
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment