Swift SDK
Install the Voidhash iOS SDK and create its client.
The Swift SDK adds paywalls, purchases, access checks, feature flags and analytics to native iOS apps built on StoreKit 2. To add it to an app for the first time, follow the Swift quickstart. Options and methods are in the Swift SDK reference.
Requirements
- iOS 15 or later. Paywalls need UIKit.
- A Swift 6 toolchain. The sources also build in the Swift 5.9 language mode.
- StoreKit 2.
The sources also build for visionOS and for app extensions, such as widgets.
Install
The Swift SDK installs with Swift Package Manager from the main branch of the
Voidhash repository. In Xcode, choose
File → Add Package Dependencies…, enter https://github.com/voidhashcom/voidhash, set the
dependency rule to the main branch, and add Voidhash (and VoidhashCore when you need it) to
your app target. In a Package.swift:
dependencies: [
.package(url: "https://github.com/voidhashcom/voidhash", branch: "main")
],
targets: [
.target(
name: "App",
dependencies: [
.product(name: "Voidhash", package: "voidhash"),
.product(name: "VoidhashCore", package: "voidhash"),
]
)
]To pin a build, depend on a commit with revision: "<commit>" instead of branch: "main".
The SDK is an alpha release and has no tagged versions yet. Pin a commit and update regularly. See Versions and releases.
The SDK has three library products:
| Product | What it contains |
|---|---|
Voidhash | The client you integrate against: Voidhash.configure(…) returns a VoidhashClient. |
VoidhashCore | The shared native core. It defines the model and error types the SDK returns, such as SdkPerson, JSONValue and VoidhashStoreError. Add it and import VoidhashCore when your code names one of them. |
VoidhashUI | The native paywall renderer. Needed only to present paywalls. |
The repository URL package doesn't include VoidhashUI, whose engine ships as a binary you build
from source. To present paywalls, add the SDK from a local checkout instead, as Display a
paywall describes.
CocoaPods
The pods aren't on the CocoaPods trunk. Install their sources, the @voidhash/ios package, from the
Voidhash package registry:
npm install @voidhash/ios@https://pkg.voidha.sh/@voidhash/ios/branch:mainThen point both pods at it. Declare both: CocoaPods can't find a local VoidhashCore through the
Voidhash dependency alone.
pod "VoidhashCore", :path => "../node_modules/@voidhash/ios"
pod "Voidhash", :path => "../node_modules/@voidhash/ios"To pin a build, install from https://pkg.voidha.sh/@voidhash/ios/<hash>, using the short commit hash
at the end of the installed version, such as 83f7412 in 0.0.1-alpha.1-g83f7412. Registry builds
are kept for three weeks.
Create the client
Configure one client while the app launches and keep it for the app's lifetime. In a SwiftUI app,
do it in the App initializer; in a UIKit app, in application(_:didFinishLaunchingWithOptions:).
import SwiftUI
import Voidhash
@main
struct MyApp: App {
init() {
Voidhash.configure(publishableKey: "vh_pk_...")
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}Release builds, including TestFlight and App Review builds, use the production key. Debug builds in development mode use the test key. See API keys.
configure returns the client. Everywhere else, reach it through Voidhash.shared. The examples
in these docs call it voidhash.
guard let voidhash = Voidhash.shared else { return }Don't configure the client in a let at file scope. Swift creates such a global the first time
code reads it, so the SDK wouldn't observe transactions or record the launch until then.
Initialization runs in the background: it connects to StoreKit, loads the project's configuration
and syncs transactions that happened while the app was away. The first call that needs it waits
for it. To wait explicitly, for example behind a loading screen, call
try await voidhash.waitForInitialization(). It never fails because Voidhash is unreachable.
VoidhashClient(publishableKey:options:) creates a client without starting it; call start() or
waitForInitialization() on it. Prefer Voidhash.configure, which does both and sets shared. To pass options, see
Client options.
Privacy manifest
VoidhashCore ships a privacy manifest that Xcode adds to your app's privacy report. It declares
no tracking, the UserDefaults API (reason CA92.1) and the system boot time API (reason 35F9.1),
and lists the data the SDK sends, all linked to the person and none used for tracking:
| Data type | Source | Purpose |
|---|---|---|
| User ID, device ID | The distinct ID | App functionality, analytics |
| Email address, name | What you pass to identify | App functionality |
| Purchase history | Store transactions | App functionality, analytics |
| Product interaction | Events, screens, lifecycle events | Analytics |
| Advertising data | The Apple Ads campaign behind the install | Analytics |
| Crash data | That the app crashed, and in which version; no crash logs | Analytics |
| Coarse location | City-level location derived from the request address | Analytics |
The last four are collected only while analytics consent is granted. Declare anything else you send, such as attributes or event properties that hold personal data, in your app's own privacy details.
Next steps
Something wrong or missing on this page? Tell us by email or on Discord.