Swift quickstart
Add Voidhash to a native iOS app, report your first purchase, and check access.
This guide adds Voidhash to an existing iOS app. By the end you will have the SDK installed, purchases from your own StoreKit code reported to Voidhash, and an access check that gates a premium feature.
The initial release is observer-only
SDK-started purchases and hosted paywalls are temporarily unavailable. Your app keeps buying and finishing transactions with StoreKit, and the SDK reports them to Voidhash.
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.
- Your app already sells at least one product with StoreKit 2, or you are about to add one.
Install the SDK
Add the SDK package to your app target. In Xcode, open File → Add Package Dependencies…, enter
https://github.com/voidhashcom/voidhash, set the dependency rule to the main branch, 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", branch: "main")
],
targets: [
.target(name: "App", dependencies: [.product(name: "Voidhash", package: "voidhash")])
]The repository has no release tags yet, so the dependency follows the main branch. Pin a commit
with revision: when you need a reproducible build.
The package ships two products. Voidhash is the SDK you integrate against. VoidhashCore
is the shared native core it depends on. Add VoidhashCore to your target as well when your code
names one of its types, such as SdkPerson or VoidhashStoreError, and import it where you do.
To install with CocoaPods instead, see Compatibility.
Configure the client
Configure the client once, while the app launches, with your project's publishable key. In a
SwiftUI app, do it in the App initializer.
import SwiftUI
import Voidhash
@main
struct MyApp: App {
init() {
Voidhash.configure(publishableKey: "vh_pk_...")
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}In a UIKit app, call Voidhash.configure from application(_:didFinishLaunchingWithOptions:).
Everywhere else, reach the client through Voidhash.shared. The steps below call it voidhash.
guard let voidhash = Voidhash.shared else { return }Configure the client at launch rather than in a let at file scope. Swift creates such a global
the first time code reads it, so the SDK would not observe transactions or record app launches
until then.
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 reports 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 product in Studio
Set up the smallest catalog that can grant access.
- Connect App Store Connect so Voidhash can verify your purchases. See Store setup for the steps.
- Create a perk such as
premium. - Create a product, attach the perk, and connect the App Store product your app sells.
For the model behind the catalog, see Products and perks.
Report purchases
Keep buying with StoreKit. After a successful purchase, report the transaction to Voidhash, then finish it as you do today.
import StoreKit
func buy(_ product: Product) async throws {
guard case .success(let verification) = try await product.purchase(),
case .verified(let transaction) = verification
else {
return
}
try await voidhash.reportTransaction(transaction)
await transaction.finish()
}reportTransaction saves the transaction on the device before it returns and delivers it in the
background, so an outage never fails your purchase flow. The SDK sends only the transaction ID;
Voidhash verifies the purchase with the App Store. The SDK also watches StoreKit for renewals and
purchases made while the app was away and reports them on its own.
The SDK never finishes a transaction. Keep finishing every transaction in your own code, including
the ones your app receives from Transaction.updates. See
Report and restore purchases for restores and recovery.
Check access
Gate a feature on an active perk grant from the person snapshot. Pass the perk slug you set in Studio.
let person = try await voidhash.getCurrentPerson()
let hasPremium = person?.hasActivePerk("premium") ?? falseThe SDK refreshes the snapshot once Voidhash accepts a reported purchase, and after a restore. See Check access for caching behavior and failure handling.
Run a test purchase
Build and run the app on a device signed into a Sandbox Apple account, and buy through your own
purchase screen. Your code finishes the transaction, and the SDK reports it without finishing it.
Once Voidhash accepts the purchase, getCurrentPerson() returns the new grant and the purchase
appears in the dashboard.
Purchases from a local StoreKit configuration file in Xcode are not reported, because the App
Store cannot verify them. The SDK reports the skip as the STOREKIT_TESTING_TRANSACTION_SKIPPED
diagnostic.