# PaywallPresentationHandler

A handler class that provides status updates for paywall presentation in register() calls.

> **Info**

Use this handler when you need fine-grained control over paywall events for a specific [`register()`](/docs/ios/sdk-reference/register) call, rather than global events via [`SuperwallDelegate`](/docs/ios/sdk-reference/SuperwallDelegate).



> **Note**

This handler is specific to the individual `register()` call. For global paywall events across your app, use [`SuperwallDelegate`](/docs/ios/sdk-reference/SuperwallDelegate) instead.



Purpose [#purpose]

Provides callbacks for paywall lifecycle events when using [`register()`](/docs/ios/sdk-reference/register) with a specific handler instance.

Signature [#signature]

```swift
@objcMembers
public final class PaywallPresentationHandler: NSObject {
  public func onPresent(_ handler: @escaping (PaywallInfo) -> Void)
  public func onWillDismiss(_ handler: @escaping (PaywallInfo, PaywallResult) -> Void)
  public func onDismiss(_ handler: @escaping (PaywallInfo, PaywallResult) -> Void)
  public func onSkip(_ handler: @escaping (PaywallSkippedReason) -> Void)
  public func onError(_ handler: @escaping (Error) -> Void)
  public func onCustomCallback(_ handler: @escaping (CustomCallback) async -> CustomCallbackResult)
}
```

Parameters [#parameters]

<TypeTable
  type="{
  onPresent: {
    type: &#x22;handler: (PaywallInfo) -> Void&#x22;,
    description: &#x22;Sets a handler called when the paywall is presented.&#x22;,
    required: true,
  },
  onWillDismiss: {
    type: &#x22;handler: (PaywallInfo, PaywallResult) -> Void&#x22;,
    description: &#x22;Sets a handler called when the paywall will be dismissed. Available in version 4.9.0+.&#x22;,
    required: true,
  },
  onDismiss: {
    type: &#x22;handler: (PaywallInfo, PaywallResult) -> Void&#x22;,
    description: &#x22;Sets a handler called when the paywall is dismissed.&#x22;,
    required: true,
  },
  onSkip: {
    type: &#x22;handler: (PaywallSkippedReason) -> Void&#x22;,
    description: &#x22;Sets a handler called when paywall presentation is skipped.&#x22;,
    required: true,
  },
  onError: {
    type: &#x22;handler: (Error) -> Void&#x22;,
    description: &#x22;Sets a handler called when an error occurs during presentation.&#x22;,
    required: true,
  },
  onCustomCallback: {
    type: &#x22;handler: (CustomCallback) async -> CustomCallbackResult&#x22;,
    description: &#x22;Sets an async handler called when the paywall requests a custom callback. The handler receives a CustomCallback with a name and optional variables, and returns a CustomCallbackResult indicating success or failure. Available in version 4.12.10+.&#x22;,
    required: false,
  },
}"
/>

Returns / State [#returns--state]

Each method returns `Void` and configures the handler for the specific paywall lifecycle event.

Usage [#usage]

Basic handler setup:

```swift
func registerFeatureWithHandler() {
  let handler = PaywallPresentationHandler()
  
  handler.onPresent { paywallInfo in
    print("Paywall presented: \(paywallInfo.id)")
    // Pause background tasks, analytics, etc.
  }
  
  handler.onWillDismiss { paywallInfo, result in
    print("Paywall will dismiss: \(paywallInfo.id)")
    // Prepare for dismissal, save state, etc.
  }
  
  handler.onDismiss { paywallInfo, result in
    print("Paywall dismissed with result: \(result)")
    
    switch result {
    case .purchased:
      showSuccessMessage()
    case .cancelled:
      showPromotionalOffer()
    case .restored:
      updateUIForActiveSubscription()
    }
  }
  
  Superwall.shared.register(
    placement: "premium_feature",
    params: ["source": "feature_screen"],
    handler: handler
  ) {
    unlockPremiumFeature()
  }
}
```

Handle skip and error cases:

```swift
let handler = PaywallPresentationHandler()

handler.onSkip { reason in
  print("Paywall skipped: \(reason)")
  
  switch reason {
  case .userIsSubscribed:
    proceedToFeature()
  case .holdout:
    proceedToFeature()
  default:
    break
  }
}

handler.onError { error in
  print("Paywall error: \(error)")
  showErrorAlert(error)
}
```

Handle custom callbacks (4.12.10+):

```swift
let handler = PaywallPresentationHandler()

handler.onCustomCallback { callback in
  print("Custom callback: \(callback.name)")

  // Perform your async work based on the callback name
  do {
    let result = try await performAction(named: callback.name, with: callback.variables)
    return .success(data: ["result": result])
  } catch {
    return .failure(data: ["error": error.localizedDescription])
  }
}

Superwall.shared.register(
  placement: "premium_feature",
  handler: handler
) {
  unlockPremiumFeature()
}
```

Method chaining style:

```swift
func registerWithChaining() {
  let handler = PaywallPresentationHandler()
    .onPresent { _ in pauseVideo() }
    .onDismiss { _, result in 
      resumeVideo()
      handlePurchaseResult(result)
    }
    .onError { error in showAlert(error) }
  
  Superwall.shared.register(
    placement: "remove_ads",
    handler: handler
  ) {
    hideAdsFromUI()
  }
}
```