SuperwallOptions

A configuration class for customizing paywall appearance and behavior.

Only modify networkEnvironment if explicitly instructed by the Superwall team. Use .release (default) for production apps.

Use different SuperwallOptions configurations for debug and release builds to optimize logging and behavior for each environment.

The SDK automatically chooses StoreKit 2 on iOS 15+ and falls back to StoreKit 1 on older versions, but you can override this with storeKitVersion.

Purpose

Configures various aspects of Superwall behavior including paywall presentation, networking, logging, and StoreKit version preferences.

Signature

@objcMembers
public final class SuperwallOptions: NSObject {
  public var paywalls: PaywallOptions
  public var storeKitVersion: StoreKitVersion
  public var networkEnvironment: NetworkEnvironment
  public var logging: LoggingOptions
  public var localeIdentifier: String?
  public var shouldBypassAppTransactionCheck: Bool
  public var eventTrackingBehavior: EventTrackingBehavior
  @available(*, deprecated, renamed: "eventTrackingBehavior")
  public var isExternalDataCollectionEnabled: Bool
  public var testModeBehavior: TestModeBehavior
  public enum DevServer: Equatable {
    case `default`
    case url(URL)
  }
  public var devServer: DevServer?
  public var localResources: [String: AssetResource]
  public var maxConfigRetryCount: Int
}

Parameters

Prop

Type

Local paywall development

Use devServer to render local paywall code from a running superwall dev server while keeping configuration, placements, audience evaluation, assignment, and feature gating real:

let options = SuperwallOptions()

// Simulator: discover a server on localhost ports 6100–6104.
options.devServer = .default

Superwall.configure(apiKey: "pk_your_api_key", options: options)

.default searches only ports 6100–6104. If you pass --port to superwall dev, or the server moves beyond that range because those ports are occupied, use .url(URL(string: "http://localhost:6105")!) (with the server's actual port) on the simulator.

On a physical device, use the Device URL printed by superwall dev instead of .default:

let options = SuperwallOptions()
options.devServer = .url(URL(string: "http://192.168.1.10:6100")!)

Superwall.configure(apiKey: "pk_your_api_key", options: options)

Dev server mode also activates test mode, disables paywall preloading, and skips the test mode intro sheet. It is intended for sandbox/development builds. Your host app must allow local networking for the development build:

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsLocalNetworking</key>
  <true/>
</dict>

The Objective-C-only helpers enable the same modes:

SWKSuperwallOptions *options = [[SWKSuperwallOptions alloc] init];
[options enableDevServer]; // Simulator / localhost
NSURL *deviceURL = [NSURL URLWithString:@"http://192.168.1.10:6100"]; // Device URL from `superwall dev`
[options enableDevServerWithUrl:deviceURL]; // Physical device

[Superwall configureWithApiKey:@"pk_your_api_key"
             purchaseController:nil
                         options:options
                      completion:nil];

See The Studio for the device QR flow and the settings that local paywalls inherit from their published counterparts.

Returns / State

This is a configuration object used when calling configure().

Usage

Basic options setup:

let options = SuperwallOptions()

// Configure paywall behavior
options.paywalls.shouldShowPurchaseFailureAlert = false
options.paywalls.shouldAutoShowPurchaseLoadingIndicator = true
options.paywalls.automaticallyDismiss = true

// Set StoreKit version preference
options.storeKitVersion = .storeKit2

// Configure logging
options.logging.level = .warn
options.logging.scopes = [.superwallCore, .paywallViewController]

// Set locale for testing
options.localeIdentifier = "en_GB"

// Bypass app transaction check (useful for testing)
options.shouldBypassAppTransactionCheck = true

// Control SDK event collection
options.eventTrackingBehavior = .superwallOnly

// Fail faster on a poor connection instead of retrying 6 times
options.maxConfigRetryCount = 2

// Use with configure
Superwall.configure(
  apiKey: "pk_your_api_key",
  options: options
)

Event Tracking Behavior

Use eventTrackingBehavior to decide which SDK events are sent to Superwall. Set it before configure() for the initial value, or update Superwall.shared.eventTrackingBehavior later when the user changes a privacy or consent setting.

BehaviorResult
.allSends all SDK event collection. This is the default.
.superwallOnlyKeeps internal Superwall event collection, but suppresses user-initiated Superwall.track(...) calls, trigger-fire events, and user-attribute updates.
.noneSends no SDK events to Superwall. Install-attribution matching is also skipped, so acquisition_* user attributes are not populated and audience rules that rely on them will not match.
let options = SuperwallOptions()
options.eventTrackingBehavior = .none

Superwall.configure(
  apiKey: "pk_your_api_key",
  options: options
)

isExternalDataCollectionEnabled is deprecated. Existing code that sets it to false now maps to .superwallOnly; use .none when your app needs to stop SDK event collection entirely.

PaywallOptions configuration:

let paywallOptions = PaywallOptions()

// Presentation behavior
paywallOptions.shouldShowPurchaseFailureAlert = false
paywallOptions.shouldAutoShowPurchaseLoadingIndicator = true
paywallOptions.automaticallyDismiss = true

// Transaction behavior  
paywallOptions.transactionTimeout = 30.0 // seconds
paywallOptions.restoreFailedPurchaseAlert.title = "Restore Failed"
paywallOptions.restoreFailedPurchaseAlert.message = "Please try again"

// Product overrides
paywallOptions.overrideProductsByName = [
  "primary": "produceID_to_replace_primary_product"
]
// Assign to main options
options.paywalls = paywallOptions

Logging configuration:

let loggingOptions = LoggingOptions()
loggingOptions.level = .debug
loggingOptions.scopes = [.all] // or specific scopes like [.superwallCore, .network]

options.logging = loggingOptions

Real-world example for production:

func configureSuperwallForProduction() {
  let options = SuperwallOptions()
  
  // Minimal logging for production
  options.logging.level = .error
  
  // Customize paywall behavior
  options.paywalls.shouldShowPurchaseFailureAlert = true
  options.paywalls.automaticallyDismiss = true
  
  // Use StoreKit 2 for better performance on iOS 15+
  options.storeKitVersion = .storeKit2
  
  Superwall.configure(
    apiKey: "pk_your_production_api_key",
    options: options
  )
}

Debug configuration for development:

func configureSuperwallForDebug() {
  let options = SuperwallOptions()
  
  // Verbose logging for debugging
  options.logging.level = .debug
  options.logging.scopes = [.all]
  
  // Show detailed error alerts
  options.paywalls.shouldShowPurchaseFailureAlert = true
  
  // Test with specific locale
  options.localeIdentifier = "es_ES"
  
  Superwall.configure(
    apiKey: "pk_your_test_api_key",
    options: options
  )
}

Runtime Interface Style Configuration

While SuperwallOptions provides initial configuration, you can dynamically change the interface style (light/dark mode) for paywalls at runtime using:

// Force dark mode for all paywalls
Superwall.shared.setInterfaceStyle(to: .dark)

// Force light mode for all paywalls  
Superwall.shared.setInterfaceStyle(to: .light)

// Revert to system default
Superwall.shared.setInterfaceStyle(to: nil)

Use this method if you have a themeing system that is different than the system.

The change takes effect immediately and persists until changed again or the app restarts.

How is this guide?

On this page