Swift quickstart

Add Voidhash to a native iOS app and show your first paywall.

This guide adds Voidhash to an existing iOS app. By the end you will have the SDK installed, a paywall on screen, and an access check that gates a premium feature.

Before you start

  • Your app targets iOS 15 or later.
  • You build with a Swift 6 toolchain. The sources also build in the Swift 5.9 language mode.

Install the SDK

Add the SDK package to your app target. In Xcode, open File → Add Package Dependencies…, enter https://github.com/voidhashcom/voidhash, and add the Voidhash library to your app target.

If you manage dependencies in a Package.swift, add the package there instead:

dependencies: [
    .package(url: "https://github.com/voidhashcom/voidhash", from: "0.0.1-alpha.1")
],
targets: [
    .target(name: "App", dependencies: [.product(name: "Voidhash", package: "voidhash")])
]

The package ships two products. Voidhash is the SDK you integrate against. VoidhashCore is the shared native core it depends on. You only touch VoidhashCore directly if you build on top of the engine yourself.

Configure the client

Create the client once at app start with your project's publishable key.

App.swift
import Voidhash

let voidhash = Voidhash.configure(publishableKey: "vh_pk_...")

The publishable key is safe to include in the app. Never ship vh_sk_... secret keys.

configure starts initialization in the background. Initialization connects to the store, fetches the project schema, and reconciles any transactions that happened while the app was away. The first call that needs initialization waits for it implicitly. To wait explicitly, for example on a loading screen, call await voidhash.waitForInitialization().

Configure one test offer in Studio

Set up the smallest catalog that can show a paywall and grant access.

  1. Create a perk such as premium.
  2. Create a product, choose its billing duration, and attach the perk.
  3. Create a paywall that includes the product, then publish it.
  4. Create a paywall location such as onboarding and assign the published paywall.

Connect App Store Connect before you test a release build. See Store setup for the steps. For the model behind the catalog, see Products and perks and Paywalls.

Present the paywall

Resolve the paywall assigned to a location and present it.

final class Paywalls: VoidhashPaywallDelegate {
    func paywall(_ location: String, didPurchaseProductId productId: String, requestId: String?) {
        unlockPremium()
    }

    func paywallDidDismiss(_ location: String) {}
}

let result = try await voidhash.presentPaywall(location: "onboarding", delegate: paywallsDelegate)

if result != .shown {
    // `notAssigned` is the expected case when the location has no published
    // paywall. Fall back to your own screen instead of leaving the customer
    // with nothing.
    showFallbackUpgradeScreen()
}

The SDK looks up the paywall assigned to the location and presents it in a full-screen WebView. It speaks the paywall bridge protocol natively, so the paywall's actions work without extra code. Purchases and restores started inside the paywall run through the same purchase pipeline. Close dismisses the paywall. External links open in the browser. Custom events are captured into analytics.

The SDK holds the delegate weakly. Keep a strong reference to it while the paywall is presented.

Check access

Gate a feature on an active perk grant from the person snapshot.

let person = try await voidhash.getCurrentPerson()

let hasPremium = person?.entitlements.grants.contains {
    $0.perkId == "premium" && $0.status == "active"
} ?? false

The snapshot refreshes after a successful purchase or restore. See Check access for caching behavior and failure handling.

Run a test purchase

Build and run the app, then buy through the presented paywall. Use a device or simulator signed into a Sandbox Apple account.

Purchases sync to the server first. The SDK finishes the transaction with StoreKit only after validation succeeds, then refreshes the person snapshot.

Next steps