Xee Docs
Get started

Install & configure iOS SDK

View as Markdown

Add the Xee SDK to your iOS app with Swift Package Manager, then activate it once at launch with your SDK key. Every other SDK call depends on this step.

Requirements

  • iOS 13 or later (macOS 11 and visionOS 1 are also supported).
  • An Xcode version that supports Swift tools 6.0 (Xcode 16 or later).
  • Swift Package Manager. The SDK is not published to CocoaPods.
  • An app in Xee with its bundle ID set in App settings, iOS SDK.

Install the SDK

  1. In Xcode, choose File, Add Package Dependencies.
  2. Paste the repository URL into the search field: https://github.com/xee-ai/XeeSDK-iOS
  3. Choose a dependency rule and click Add Package. The repository has no version tags yet, so choose Branch and enter main.
  4. In the list of package products, add Xee to your app target. XeeLogger comes with it; add it to a target yourself only if that target imports XeeLogger directly.
  5. Click Add Package. Xee now appears under Package Dependencies in the project navigator.

To add it from a Package.swift instead, declare the dependency and the product:

Package.swift
dependencies: [
    .package(url: "https://github.com/xee-ai/XeeSDK-iOS", branch: "main")
],
targets: [
    .target(name: "YourApp", dependencies: [.product(name: "Xee", package: "XeeSDK-iOS")])
]

Get your SDK key

Open App settings, iOS SDK in the Xee dashboard. The SDK section shows:

ValueWhat it is
SDK keyThe public key for this app. It starts with xee_.
Notification URLWhere Apple sends App Store Server Notifications for this app: renewals, expiry, cancellations and refunds.

Each app in Xee has its own SDK key, so pick the right app if you have several. If Claude does the integration through the Xee MCP, it reads the key and the bundle ID for you with list_apps, so you do not have to paste them. The key is public: it is meant to ship inside your app. If it leaks somewhere you did not intend, rotate it on the same tab and ship the new one.

Activate the SDK

Call Xee.activate(withAPIKey:) with your SDK key. Call it once per app launch, as early as you can. A second call throws an error.

import SwiftUI
import Xee

@main
struct YourApp: App {
    init() {
        Task {
            do {
                try await Xee.activate(withAPIKey: "xee_YOUR_SDK_KEY")
            } catch {
                // error is a XeeError: log it and keep the app usable
            }
        }
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

If you prefer callbacks, pass a completion handler. It receives an optional XeeError:

Swift
Xee.activate(withAPIKey: "xee_YOUR_SDK_KEY") { error in
    if let error {
        // error is a XeeError: log it and keep the app usable
    }
}

Activate with a configuration

When you need more than the key, build an XeeConfiguration and call Xee.activate(with:). The builder sets the log level, the customer user ID and app account token, observer mode and the other options under Optional setup below. This example turns on verbose logs:

Swift
let configuration = XeeConfiguration
    .builder(withAPIKey: "xee_YOUR_SDK_KEY")
    .with(logLevel: .verbose) // for development; remove or lower for release
    .build()

Task {
    do {
        try await Xee.activate(with: configuration)
    } catch {
        // error is a XeeError: log it and keep the app usable
    }
}

Xee.activate(with: configuration) { error in ... } is the callback form. It passes an optional XeeError to the closure.

If you already know who the user is at launch, add their ID to the same configuration. See Identify users.

Next steps

Optional setup

All of these are methods on the configuration builder. Chain the ones you need before .build().

Logging

The SDK logs at the level you choose. The default is info.

LevelWhat is logged
errorErrors only.
warnErrors, plus problems that are not critical but worth a look.
infoWarnings, plus messages about the SDK's lifecycle.
verboseEverything above, plus method calls and requests. Use it while developing and for your first release.
debugThe most detail, for debugging the SDK itself.

Set it on the builder with .with(logLevel:), or at any time with Xee.logLevel:

Swift
Xee.logLevel = .verbose

To send the SDK's log messages to your own logging or to a file, register a handler. It is called for each message at the current level, in addition to the default output:

Swift
Xee.setLogHandler { record in
    writeToLogFile("Xee \(record.level): \(record.message)")
}

Data collection

By default the SDK collects the advertising identifier (IDFA) and the device's IP address. Turn either off when you do not need them, for example to stay clear of the App Tracking Transparency prompt or to collect less data under GDPR or CCPA. Both default to false.

Swift
let configuration = XeeConfiguration
    .builder(withAPIKey: "xee_YOUR_SDK_KEY")
    .with(idfaCollectionDisabled: true)
    .with(ipAddressCollectionDisabled: true)
    .build()

Clear data after a backup restore

With .with(clearDataOnBackup: true), the SDK notices when the app was restored from an iCloud backup and deletes its local data: the cached profile, products and paywalls. It then starts clean. The default is false.

Only the SDK's local cache is removed. The user's purchases with Apple and their profile in Xee stay as they are.

Transaction finishing

By default the SDK finishes each StoreKit transaction once it has handled it. If you want to run your own checks first, set .with(transactionFinishBehavior: .manual). You then finish transactions yourself: implement onUnfinishedTransaction(_:) in your XeeDelegate, or call Xee.getUnfinishedTransactions(), and call finish() on each transaction when you are done. Both need iOS 15 or later.

Callback queue

Completion handlers and delegate methods run on the main queue. To use another queue, pass it with .with(callbackDispatchQueue:).