Configuring the SDK

As soon as the app is launched, you need to configure the SDK with your Public API Key. You'll retrieve this from the Superwall settings page.
If you haven't already, sign up for a free account on Superwall. Then, when you're through to the Dashboard, click the Settings icon in the top right corner, and select Keys:

On that page, you will see your Public API Key. Copy this for the next step.

It is recommended to create a service class that handles your SDK configuration and delegate callbacks. Create a new file PaywallService.swift, then add the following:

import Paywall

final class PaywallService {
  static let apiKey = "MYAPIKEY" // Replace this with your API Key
  static var shared = PaywallService()

  static func initPaywall() {
    let options = PaywallOptions()
    // Uncomment to show debug logs
    // options.logging.level = .debug

    Paywall.configure(
      apiKey: apiKey,
      delegate: shared,
      options: options
    )
  }
}
// PaywallService.h
#import <Foundation/Foundation.h>

@interface PaywallService : NSObject 

+ (id)shared;
+ (void)initPaywall;

@end

// PaywallService.m
#import <Foundation/Foundation.h>
#import "PaywallService.h"

@import Paywall;

NSString *const API_KEY = @"MYAPIKEY"; // Replace this with your API Key

@interface PaywallService () <PaywallDelegate>

@end

@implementation PaywallService

#pragma mark Singleton Methods

+ (id)shared {
  static PaywallService *sharedMyManager = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
      sharedMyManager = [[self alloc] init];
  });
  return sharedMyManager;
}

+ (void)initPaywall {
   [Paywall configureWithApiKey:API_KEY userId:nil delegate:shared];
    
   // Uncomment to show debug logs
   // [Paywall setDebugMode: true];
}

@end

This configures a shared instance of Paywall for use throughout your app and sets the delegate to the PaywallService shared instance. Make sure to replace the apiKey with your public API key that you just retrieved.
You can also optionally identify a user in the configure function. For more information, see Identifying Users.

Conforming to the Delegate

Next, extend PaywallService and make it conform to PaywallDelegate:

import StoreKit

// MARK: - Paywall Delegate
extension PaywallService: PaywallDelegate {
  // 1
  func purchase(product: SKProduct) {
    // TODO: Purchase the product here
  }

  // 2
  func restorePurchases(completion: @escaping (Bool) -> Void) {
    // TODO: Restore purchases and call completion block with boolean indicating
    // the success status of restoration
    completion(false)
  }

  // 3
  func isUserSubscribed() -> Bool {
    // TODO: Replace with boolean indicating the user's subscription status
    return false
  }
}
import RevenueCat

// MARK: - Paywall Delegate
extension PaywallService: PaywallDelegate {
  // 1
  func purchase(product: SKProduct) {
    Task {
      do {
        let result = try await Purchases.shared.purchase(product: StoreProduct(sk1Product: product))
        // React to the purchase here
      } catch {
        // Handle purchase error here
      }
    }
  }

  // 2
  func restorePurchases(completion: @escaping (Bool) -> Void) {
    Task {
      do {
        let purchaserInfo = try await Purchases.shared.restorePurchases()
        
        // check purchaserInfo to see if subscription "MyEntitlement" is now active
        let restored = purchaserInfo.entitlements.all["MyEntitlement"]?.isActive == true
        
        completion(restored)
      } catch {
        completion(false)
      }
    }
  }

  // 3
  func isUserSubscribed() -> Bool {
    // TODO: Replace with boolean indicating the user's subscription status.
    // You can obtain this via await Purchases.shared.customerInfo() and
    // checking the entitlements. Ideally you will have a local state indicating
    // subscription status.
    return false
  }
}
// Add to PaywallService.m

// 1
- (void)purchaseWithProduct:(SKProduct * _Nonnull)product {
  // TODO: Purchase the product here
}

// 2
- (void)restorePurchasesWithCompletion:(void (^ _Nonnull)(BOOL))completion {
  // TODO: Restore purchases and call completion block with boolean indicating
  // the success status of restoration
  completion(false);
}

// 3
- (BOOL)isUserSubscribed {
  // TODO: Replace with boolean indicating the user's subscription status
  return false;
}

These delegate methods are mandatory and receive callbacks from the SDK in response to certain events that happen on the paywall. It is up to you to fill these methods with the appropriate code. Here's what each method is responsible for:

  1. Purchasing a given product. In here, enter your code that you use to purchase a product.
  2. Restoring purchases. Make sure to call the completion block after you attempt to restore purchases to let the SDK know whether the restoration was successful or not.
  3. Telling the SDK whether the user has an active subscription. Replace this with a boolean indicating the user's subscription status.

Next, open AppDelegate.swift. Then, call initPaywall() from application(_:didFinishLaunchingWithOptions:). If you don't have an app delegate due to using SwiftUI you'll need to create the file and then follow the steps in the code below:

import Paywall

final class AppDelegate: UIResponder, UIApplicationDelegate {
  func application(
    _ application: UIApplication, 
    didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?
  ) -> Bool {
    PaywallService.initPaywall()
  )
}
// At the top of your main App class:

@main
struct MyApp: App {
  @UIApplicationDelegateAdaptor(AppDelegate.self) private var appDelegate
  
  // etc...
}


// Inside AppDelegate.swift:

final class AppDelegate: UIResponder, UIApplicationDelegate {
  func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
  ) -> Bool {
    PaywallService.initPaywall()
  }
}
#import <Paywall/Paywall-Swift.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [PaywallService initPaywall];
    return YES;
}
@protocol SKPaymentTransactionObserver;
@protocol SKProductsRequestDelegate;
#import <Paywall/Paywall-Swift.h> 
  
 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [PaywallService initPaywall];
    return YES;
}

You've now configured Paywall!


What’s Next
Did this page help you?