Skip to content

iOS SDK reference

The iOS SDK returns a RevokeGPT token from one call. It solves a proof of work on the device, attests the app with App Attest (DeviceCheck where App Attest is unsupported) and, when your site’s rules ask for it, shows the hosted challenge in a sheet. Your server then verifies the token with siteverify. It needs iOS 15 or later and Swift 6 (Xcode 16 or later), with no third-party dependencies. For a step-by-step setup see the iOS quickstart.

In Xcode: File, Add Package Dependencies, Add Local, choose sdks/ios. Or in Package.swift:

.package(path: "../path/to/sdks/ios"),
// target: .product(name: "RevokeGPT", package: "ios")

After the first release use Swift Package Manager with https://github.com/revokegpt/revokegpt-ios, from 0.1.0. CocoaPods works from git only; the pod is never published to the CocoaPods trunk.

Add the App Attest capability to your app target, and add your app (Team ID and bundle id) under Apps in the dashboard. For the DeviceCheck fallback, also upload your DeviceCheck key there.

Configuration is a struct passed to configure.

Configuration(
siteKey: String, endpoint: URL = Configuration.defaultEndpoint,
widgetOrigin: URL = Configuration.defaultWidgetOrigin, timeout: TimeInterval = 10,
locale: String? = nil, theme: Theme = .auto, keyScope: String? = nil,
debugLogging: Bool = false
)
Setting Default Notes
siteKey required rgpk_ and 20 letters and digits.
endpoint https://api.revokegpt.com https:; plain http: only to 127.0.0.1, localhost or ::1 in a Debug build.
widgetOrigin https://js.revokegpt.com The hosted challenge page’s origin, a bare origin. The same scheme rules apply.
timeout 10 s 1 to 60 s. Covers the network calls, the proof of work and the attestation, not the time the sheet is on screen.
locale the app’s language The hosted page’s language (en, pt-BR, …).
theme .auto .light, .dark or .auto.
keyScope none An opaque id of the signed-in account, for one App Attest key per account on the device. Use an opaque value, not an email. Changing it starts a fresh key.
debugLogging off Logs event names to os.Logger (subsystem com.revokegpt). Logs never contain a value.

Presentation says where a challenge sheet may appear: .automatic (the top-most view controller of the key window), .viewController { ... } (one you name; nil means challenge-required) or .never.

All methods are on RevokeGPT.shared.

func configure(_ configuration: Configuration) async throws(RevokeGPTError)

Call once at launch. A later call replaces the configuration (a new site key takes effect on the next call). Throws invalid-argument (naming the first bad field) or busy while a call is running.

try await RevokeGPT.shared.configure(Configuration(siteKey: "rgpk_..."))
func execute(
action: String? = nil, cdata: String? = nil, presentation: Presentation = .automatic
) async throws(RevokeGPTError) -> String

Returns the RevokeGPT token. action is 1 to 100 of A-Z a-z 0-9 / _. cdata is 0 to 255 of A-Z a-z 0-9 _ -. Calls may run concurrently. Cancelling the Swift task cancels the call (cancelled) and closes the sheet.

do {
let token = try await RevokeGPT.shared.execute(action: "login")
// Send `token` to your server with the login request.
} catch let error as RevokeGPTError {
// error.code
}
func challengeAccount(
requestToken: String, languageCode: String? = nil, presentation: Presentation = .automatic
) async throws(RevokeGPTError) -> String

Account verification: shows the hosted page for the request token your server got from RevokeGPT and returns the token the page produces.

func prewarm() async

Generates the App Attest key ahead of time, so the first execute only attests it. Does nothing before configure or where App Attest is unavailable. Optional.

RevokeGPTError is an enum with a code string, a description and, on .httpError and .api, retryAfterSeconds. The description carries only the code, the status and the server’s request id: never a token, a site key or a server message.

Code Meaning
invalid-argument A setting or argument is malformed; invalidArgument(field:) names it.
not-configured execute before configure.
network-error No connection, a TLS failure or a refused connection.
timeout The call’s deadline passed.
http-error A non-200 answer without a known error, or a redirect (never followed).
invalid-response The answer was not valid, or it named another app.
challenge-required A challenge is needed and could not be shown (.never, or no window). No token is returned.
challenge-unsupported The device cannot show the challenge safely.
cancelled The person closed the challenge, or your task was cancelled.
busy configure during a call, or a second sheet while one is up.
internal An unexpected state.
API codes For example rate-limited, invalid-site-key, app-not-allowed, plan-required, passed through unchanged.

Never retry in a tight loop. There is no option to skip a challenge, so your server never receives a low-score token presented as a passed one. See errors for the API codes.

  • Simulator: it has no App Attest. The SDK sends no attestation, or a DeviceCheck token, and the token carries a lower score. Test the real flow on a device.
  • App extensions: the SDK builds there, but App Attest is unsupported in most types and no sheet can be shown (challenge-required). App Clips are not supported.
  • Local development: point endpoint and widgetOrigin at http://127.0.0.1:... in a Debug build. Your Debug Info.plist needs NSAppTransportSecurity > NSAllowsLocalNetworking.
  • Use the development App Attest environment while you develop and production for TestFlight and the App Store.
  • Only the public site key goes in the app. The secret key stays on your server: verify the token with siteverify and check success, the action and the app (siteverify returns ios_bundle_id in place of hostname). The server SDKs take expectedApp with platform ios. See the Go and Java references.
  • The SDK never reads the advertising identifier, identifierForVendor, the device name, location, contacts or installed apps. It stores only the App Attest key id, in the Keychain (this device only, never synced).
  • The package ships a privacy manifest: no tracking, one collected data type (Other Diagnostic Data, for fraud prevention and security), no required-reason APIs.
  • The challenge sheet is a WKWebView of https://js.revokegpt.com only. No cookies or storage are kept after it closes, no other site can load in it, and it accepts messages only from the page itself.