Hooking up Superwall placements to 3rd party tools

SuperwallKit automatically registers some internal placements. You can view the list of placements here. We encourage you to also track them in your own analytics by implementing the Superwall delegate. Using the handleSuperwallPlacement(withInfo:) function, you can forward events to your analytics service:

extension SuperwallService: SuperwallDelegate {
  func handleSuperwallPlacement(withInfo placementInfo: SuperwallPlacementInfo) {
    print("analytics placement called", placementInfo.placement.description)
    MyAnalyticsService.shared.track(
      event: placementInfo.placement.description,
      params: placementInfo.params
    )
  }
}

You might also want to set user attribute to allow for Cohorting in 3rd Party Tools

You might also want to set user attribute to allow for Cohorting in 3rd Party Tools

Alternatively, if you want typed versions of all these placements with associated values, you can access them via placementInfo.placement:

func handleSuperwallPlacement(withInfo placementInfo: SuperwallPlacementInfo)  {
  switch placementInfo.placement {
    case .firstSeen:
      break
    case .appOpen:
      break
    case .appLaunch:
      break
    case .identityAlias:
      break
    case .appInstall:
      break
    case .sessionStart:
      break
    case .deviceAttributes(let attributes):
      break
    case .subscriptionStatusDidChange:
      break
    case .appClose:
      break
    case .deepLink(let url):
      break
    case .triggerFire(let placementName, let result):
      break
    case .paywallOpen(let paywallInfo):
      break
    case .paywallClose(let paywallInfo):
      break
    case .paywallDecline(let paywallInfo):
      break
    case .transactionStart(let product, let paywallInfo):
      break
    case .transactionFail(let error, let paywallInfo):
      break
    case .transactionAbandon(let product, let paywallInfo):
      break
    case .transactionComplete(let transaction, let product, let type, let paywallInfo):
      break
    case .subscriptionStart(let product, let paywallInfo):
      break
    case .freeTrialStart(let product, let paywallInfo):
      break
    case .transactionRestore(let restoreType, let paywallInfo):
      break
    case .transactionTimeout(let paywallInfo):
      break
    case .userAttributes(let atts):
      break
    case .nonRecurringProductPurchase(let product, let paywallInfo):
      break
    case .paywallResponseLoadStart(let triggeredPlacementName):
      break
    case .paywallResponseLoadNotFound(let triggeredPlacementName):
      break
    case .paywallResponseLoadFail(let triggeredPlacementName):
      break
    case .paywallResponseLoadComplete(let triggeredPlacementName, let paywallInfo):
      break
    case .paywallWebviewLoadStart(let paywallInfo):
      break
    case .paywallWebviewLoadFail(let paywallInfo):
      break
    case .paywallWebviewLoadComplete(let paywallInfo):
      break
    case .paywallWebviewLoadTimeout(let paywallInfo):
      break
    case .paywallWebviewLoadFallback(let paywallInfo):
      break
    case .paywallProductsLoadStart(let triggeredPlacementName, let paywallInfo):
      break
    case .paywallProductsLoadFail(let triggeredPlacementName, let paywallInfo):
      break
    case .paywallProductsLoadComplete(let triggeredPlacementName):
      break
    case .paywallProductsLoadRetry(let triggeredPlacementName, let paywallInfo, let attempt):
      break
    case .surveyResponse(let survey, let selectedOption, let customResponse, let paywallInfo):
      break
    case .paywallPresentationRequest(let status, let reason):
      break
    case .touchesBegan:
      break
    case .surveyClose:
      break
    case .reset:
      break
    case .restoreStart:
      break
    case .restoreFail(let message):
      break
    case .restoreComplete:
      break
    case .configRefresh:
      break
    case .customPlacement(let name, let params, let paywallInfo):
      break
    case .configAttributes:
      break
    case .confirmAllAssignments:
      break
    case .configFail:
      break
    case .adServicesTokenRequestStart:
      break
    case .adServicesTokenRequestFail(let error):
      break
    case .adServicesTokenRequestComplete(let token):
      break
    case .shimmerViewStart:
      break
    case .shimmerViewComplete:
      break
    }
}

Using placements to see purchased products

If your goal is simply to view which product was purchased from a paywall, you don’t need a purchase controller for that (though it can be done in one). Using a SuperwallDelegate, you can leverage the transactionComplete placement, which provides direct access to the purchased product via product:

import SwiftUI
import SuperwallKit

class SWDelegate: SuperwallDelegate {
    func handleSuperwallPlacement(withInfo placementInfo: SuperwallPlacementInfo) {
        switch placementInfo.placement {
        case .transactionComplete(let transaction, let product, let paywallInfo):
            print("Converted from paywall: \(product.productIdentifier)")
        default:
            print("\(#function) - \(placementInfo.placement)")
        }
    }
}

@main
struct AwesomeApp: App {

    init() {
        Superwall.configure(apiKey: "MY_API_KEY")
        Superwall.shared.delegate = self.swDelegate
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
                .onAppear { Superwall.shared.register(placement: "test_placement") }
        }
    }
}

In that example, as soon as a user converts on a paywall, the product identifier will be printed to the console:

Converted from paywall: ex.someProduct.identifier

In addition, you can use a PaywallPresentationHandler to view any purchased product:

let handler = PaywallPresentationHandler()
handler.onDismiss { info, result in
    switch result {
    // Purchased product reported here...
    case .purchased(let product):
        print("Bought \(product)")
    default:
        print("Handle other results...")
    }
}

Superwall.shared.register(placement: "myPlacement", handler: handler) {
    print("Feature unlocked.")
}