Skip to main content

Overview

try await Encore.shared.placement(_:).show() returns a PresentationResult. You can either branch on the returned value at the call site (async-result) or register global onPurchaseRequest / onPassthrough handlers (handler-based). Both work; pick whichever fits the call site. For the cross-platform decision tree, see Integration Patterns.

Async-result pattern

Use this when the place you call show() from already has access to your purchase + decline logic.

Basic example

From SwiftUI

Button action bodies are synchronous, so wrap in Task:

Result type

See PresentationResult and NotGrantedReason.

Handler pattern

Use this when the show() call site is a third-party delegate (Superwall, RevenueCat) or a UI action that doesn’t have direct access to your purchase code.

Register at app launch

Then show() from anywhere

The handlers fire when the placement resolves. The result of show() is ignored — control flow lives in the handlers.

When to use which

  • Async-result — call site already imports your billing client. Branch-specific code lives at the call site.
  • Handler — Encore is invoked from third-party paywall delegates (Superwall, RevenueCat) or from many UI sites that share post-purchase logic.
  • Mixed — register a handler for cross-cutting analytics, and still branch on await show() for site-specific UI navigation.
See the decision tree for the full rationale.

Re-registration semantics

Each handler setter replaces the previous closure. There is no double-firing. You don’t need to call any removeHandler API.

Platform-specific notes

  • Task { } wrappingshow() is async throws; SwiftUI Button actions and UIKit @IBAction selectors are synchronous, so wrap the call in Task { ... }.
  • PresentationResult is non-throwing in the success pathtry await show() only throws on transport / SDK errors. The “user dismissed” case is .notGranted(...), not a thrown error.
  • Encore is the entry pointEncore is a public final class conforming to EncoreProtocol. Access it via Encore.shared. (There is no EncoreClient typealias.)
  • Handler signatureonPurchaseRequest’s closure is (PurchaseRequest) async throws -> Bool; you can await directly inside it without a manual Task. Return true on a successful purchase so Encore auto-dismisses the offer sheet.

See also