Skip to content

iOS SDK

Install the EuCaptcha library to integrate EU CAPTCHA into your iOS application.

Package Version
EuCaptcha 1.0.0

Server-side verification is identical regardless of client platform — see Server-Side Verification. For other mobile integrations see Android SDK and Flutter.


Requirements

  • iOS 13.0 or later
  • Swift 5.5+
  • Xcode 13+

Installation

In Xcode, go to File > Add Package Dependencies and enter the repository URL, or add it directly to Package.swift:

dependencies: [
    .package(url: "https://github.com/Myra-Security-GmbH/eu-captcha-ios-sdk.git", from: "1.0.0")
]

Basic usage

1. Create a widget

Call the static factory method from wherever you set up your view controller:

import EuCaptcha

let widget = EuCaptchaSDK.createWidget(
    sitekey: "EUCAPTCHA_SITE_KEY",
    theme: .auto,    // .light, .dark, or .auto (follows system appearance)
    language: "en"   // BCP 47 language tag; defaults to device language
)

2. Handle events

Assign closures to the widget before embedding its view:

widget.onComplete = { [weak self] event in
    // event.response is the token — send it to your server
    DispatchQueue.main.async {
        self?.submitButton.isEnabled = true
        self?.captchaToken = event.response
    }
}

widget.onExpire = { [weak self] _ in
    DispatchQueue.main.async {
        self?.submitButton.isEnabled = false
    }
}

widget.onError = { [weak self] _ in
    DispatchQueue.main.async {
        self?.showErrorMessage()
    }
}

3. Embed the widget view controller

Obtain the widget's UIViewController and add it as a child:

let widgetVC = widget.viewController()
addChild(widgetVC)
widgetVC.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(widgetVC.view)
widgetVC.didMove(toParent: self)

NSLayoutConstraint.activate([
    widgetVC.view.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
    widgetVC.view.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16),
    widgetVC.view.heightAnchor.constraint(equalToConstant: EuCaptchaSDK.preferredHeight),
])

EuCaptchaSDK.preferredHeight is 70 pt. EuCaptchaSDK.maxWidth is 420 pt.

4. Submit the token

Pass the token from event.response to your server as the eu-captcha-response field. After a rejected submission, call widget.reset() so the user can complete a new challenge.

Customisation

EuCaptchaSDK.createWidget() parameters:

Parameter Type Default Description
sitekey String Your public sitekey (required)
theme EuCaptchaWidgetTheme .auto .light, .dark, or .auto (follows system appearance)
language String? nil BCP 47 language tag (e.g. "en", "de"). Defaults to the device language.

Event callbacks

Assign closures directly to properties on EuCaptchaWidget. All callbacks are delivered on the thread the widget's web view uses — dispatch to the main thread before updating the UI.

Property Event type Fired when
onComplete EuCaptchaWidgetCompleteEvent The challenge finishes successfully. event.response holds the token.
onExpire EuCaptchaWidgetExpireEvent The token expires (60 minutes after completion).
onError EuCaptchaWidgetErrorEvent A network or server error occurs. event.response is ".ERROR".
onStateChange EuCaptchaWidgetStateChangeEvent Any state transition occurs. event.state and event.response reflect the new state. Covers all of the above.

Widget states

EuCaptchaWidgetState is a Swift enum reported via onStateChange and widget.state:

Case Description
.initial Widget loaded; challenge not yet started
.checking Proof-of-work challenge in progress
.completed Challenge finished — token is available in event.response
.expired Token has expired; prompt the user to retry
.error An error occurred during verification
.destroyed Widget has been destroyed

API reference

EuCaptchaSDK

All members are static. Do not instantiate this class directly.

Member Description
createWidget(sitekey:theme:language:) -> EuCaptchaWidget Creates and returns a new widget handle.
preferredHeight: CGFloat Recommended widget height in points (70).
maxWidth: CGFloat Recommended maximum widget width in points (420).

EuCaptchaWidget

Returned by EuCaptchaSDK.createWidget().

Member Type Description
state EuCaptchaWidgetState The current widget state.
response String The current token, or a sentinel value if the challenge is not yet complete.
onComplete ((EuCaptchaWidgetCompleteEvent) -> Void)? Closure called when the challenge completes.
onExpire ((EuCaptchaWidgetExpireEvent) -> Void)? Closure called when the token expires.
onError ((EuCaptchaWidgetErrorEvent) -> Void)? Closure called on error.
onStateChange ((EuCaptchaWidgetStateChangeEvent) -> Void)? Closure called on every state change.
viewController() -> UIViewController Returns the UIViewController to embed in your view hierarchy.
getResponse() -> String Alternative getter for response.
getState() -> EuCaptchaWidgetState Alternative getter for state.
reset() Reload the widget so a new challenge can be solved. Call after a rejected submission.
destroy() Release WKWebView resources. Discard the handle afterwards.

Server-side verification

After your server receives the form submission, verify the token by passing event.response as client_token to the Verification API.

For ready-made server libraries, see Server-Side Verification.