> ## Documentation Index
> Fetch the complete documentation index at: https://docs.world.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Swift

> Reference for the IDKit Swift API: request builders, presets, and polling.

Use `IDKit` for native iOS/macOS integrations backed by the same Rust core as other SDKs.

## Requirements

* iOS 15+ / macOS 12+
* Xcode 16+

## Install

Use Swift Package Manager with the published `idkit-swift` repository:

```swift theme={null}
.package(url: "https://github.com/worldcoin/idkit-swift.git", from: "<version>")
```

## Request flow

```swift theme={null}
import IDKit

let rpContext = try RpContext(
  rpId: "rp_xxxxx",
  nonce: backend.nonce,
  createdAt: backend.createdAt,
  expiresAt: backend.expiresAt,
  signature: backend.sig
)

let config = IDKitRequestConfig(
  appId: "app_xxxxx",
  action: "my-action",
  rpContext: rpContext,
  allowLegacyProofs: true,
  returnTo: "myapp://verify-done", // Optional: mobile deep-link callback URL
  environment: .production
)

let request = try IDKit.request(config: config).preset(orbLegacy(signal: "user-123"))
let connectURL = request.connectorURL
let requestID = request.requestID
```

## Presets

```swift theme={null}
import IDKit

let request = try IDKit.request(config: config).preset(
  orbLegacy(signal: "user-123")
)
```

## Polling API

* `pollStatusOnce() async -> IDKitStatus`
* `pollUntilCompletion(options:) async -> IDKitCompletionResult`
* `IDKitPollOptions(pollIntervalMs:timeoutMs:)`

```swift theme={null}
let completion = await request.pollUntilCompletion(
  options: IDKitPollOptions(pollIntervalMs: 2_000, timeoutMs: 120_000)
)

switch completion {
case .success(let result):
  print(result)
case .failure(let error):
  print(error)
}
```

## Invite-code mode

Use `presetWithInviteCode(_:)` on the builder to return an `IDKitInviteCodeRequest` instead of `IDKitRequest`. The polling surface is identical. See [Invite-code mode](/world-id/idkit/verification-flows#with-invite-code-mode) for when to use it.

```swift theme={null}
let request = try IDKit.request(config: config)
  .presetWithInviteCode(selfieCheckLegacy(signal: "user-123"))

let connectorURL = request.connectorURL  // URL with &c=<code>&a=<app_id>
let expiresAt = request.expiresAt        // Date
let completion = await request.pollUntilCompletion()
```

### Migrating from QR / connect-URL

```swift theme={null}
// Before — QR / connect-URL flow
let request = try IDKit.request(config: config)
  .preset(orbLegacy(signal: "user-123"))

let connectURL = request.connectorURL        // render as QR
let completion = await request.pollUntilCompletion()
```

```swift theme={null}
// After — invite-code mode
let request = try IDKit.request(config: config)
  .presetWithInviteCode(selfieCheckLegacy(signal: "user-123"))

let connectorURL = request.connectorURL      // display to user (URL with code embedded)
let expiresAt = request.expiresAt            // drive a countdown
let completion = await request.pollUntilCompletion()
```

The config object is unchanged. The `connectorURL` now includes `&c=<code>&a=<app_id>` params; use it alongside `expiresAt` in your UI. Polling, proof verification, and nullifier storage stay the same.

`IDKitInviteCodeRequest` exposes:

* `connectorURL: URL`
* `expiresAt: Date`
* `requestID: String`
* `pollStatusOnce() async -> IDKitStatus`
* `pollUntilCompletion(options:) async -> IDKitCompletionResult`
