Skip to main content
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:
.package(url: "https://github.com/worldcoin/idkit-swift.git", from: "<version>")

Request flow

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,
  actionDescription: "Verify user",
  bridgeUrl: nil,
  allowLegacyProofs: false,
  overrideConnectBaseUrl: nil,
  environment: .production
)

let orb = try CredentialRequest.create(
  .orb,
  options: .init(signal: "user-123")
)
let face = try CredentialRequest.create(
  .face,
  options: .init(signal: "user-123")
)

let request = try IDKit.request(config: config).constraints(anyOf(orb, face))
let connectURL = request.connectorURL
let requestID = request.requestID

Presets

import IDKit

let request = try IDKit.request(config: config).preset(
  orbLegacy(signal: "user-123")
)
Use presets only when migrating from an older IDKit version. Presets are meant to preserve compatibility with both World ID 4.0 and World ID 3.0 (legacy) flows.

Session flow

import IDKit

let sessionConfig = IDKitSessionConfig(
  appId: "app_xxxxx",
  rpContext: rpContext,
  actionDescription: "Sign in",
  bridgeUrl: nil,
  overrideConnectBaseUrl: nil,
  environment: .production
)

let createRequest = try IDKit
  .createSession(config: sessionConfig)
  .preset(orbLegacy())

let createResult = await createRequest.pollUntilCompletion()

switch createResult {
case .success(let result):
  let sessionId = result.sessionId

  let proveRequest = try IDKit
    .proveSession(sessionId: sessionId, config: sessionConfig)
    .preset(orbLegacy())

  let proveResult = await proveRequest.pollUntilCompletion()
  print(proveResult)

case .failure(let error):
  print(error.rawValue)
}
Session flows are always v4 and return sessionId in the result payload.

Polling API

  • pollStatusOnce() async -> IDKitStatus
  • pollUntilCompletion(options:) async -> IDKitCompletionResult
  • IDKitPollOptions(pollIntervalMs:timeoutMs:)
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)
}

Error codes

Swift exposes IDKitErrorCode values aligned with JS string codes:
  • user_rejected
  • verification_rejected
  • credential_unavailable
  • malformed_request
  • invalid_network
  • inclusion_proof_pending
  • inclusion_proof_failed
  • unexpected_response
  • connection_failed
  • max_verifications_reached
  • failed_by_host_app
  • generic_error
  • timeout
  • cancelled

Practical notes

  • connectorURL and requestID are validated when constructing IDKitRequest.
  • If either is invalid, Swift throws IDKitClientError.invalidConnectorURL or IDKitClientError.invalidRequestID.
  • Use IDKit.hashSignal(_:) when you need deterministic local signal hashing.