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.
Related pages