--- title: iOS / macOS-SDK --- # iOS / macOS-SDK Apple-Plattform-SDK für **iOS 15+** und **macOS 11+ (Big Sur)** via Mac Catalyst, ausgeliefert als `.xcframework` zuzüglich eines `.bundle` mit lokalisierten Assets. Drop-in für SwiftUI-, UIKit- und AppKit-Projekte. ## Demo auf GitHub ::: tip 📦 [Captcha-La/iosmacos-demo](https://github.com/Captcha-La/iosmacos-demo) — vollständiges lauffähiges Beispiel mit allen Integrationsschritten. ::: ## Installation Fügen Sie CaptchaLa Ihrem `Podfile` hinzu (CocoaPods 1.10+): ```ruby # Podfile platform :ios, '13.0' target 'YourApp' do use_frameworks! pod 'Captchala', '~> 1.0.2' end ``` ```bash pod install ``` Oder, falls Sie eine manuelle Integration bevorzugen: Laden Sie das aktuelle iOS-Release aus dem [CaptchaLa-Dashboard](https://dash.captcha.la). Das Archiv enthält: - `Captchala.xcframework` — das kompilierte SDK - `Captchala.bundle` — lokalisierte Ressourcen Legen Sie beide neben Ihre `.xcodeproj`. Das Demoprojekt referenziert sie über den Dateinamen; abgesehen davon, dass deren Speicherort stabil bleibt, ist kein manuelles Linking erforderlich. Für die manuelle Integration laden Sie das xcframework direkt herunter: [dash.captcha.la/downloads](https://dash.captcha.la/downloads) ```text YourApp/ ├── YourApp.xcodeproj ├── YourApp/ ├── Captchala.xcframework └── Captchala.bundle ``` Öffnen Sie das Projekt und führen Sie es im Simulator, auf einem Gerät oder auf **My Mac (Mac Catalyst)** aus: ```bash open YourApp.xcodeproj # Cmd-R in Xcode ``` ## Schnellstart ```swift import SwiftUI import Captchala final class CaptchaDelegateBridge: NSObject, CaptchalaDelegate { var onSuccess: ((CaptchalaResult) -> Void)? var onFailure: ((CaptchalaError) -> Void)? var onClose: (() -> Void)? func captcha(didSucceedWith result: CaptchalaResult) { onSuccess?(result) } func captcha(didFailWithError error: CaptchalaError) { onFailure?(error) } func captchaDidClose() { onClose?() } } struct LoginView: View { @State private var bridge = CaptchaDelegateBridge() @State private var status = "Tap to verify" var body: some View { Button("Verify with CAPTCHA", action: startVerify) Text(status).font(.caption) } private func startVerify() { bridge.onSuccess = { r in // Send r.passToken to your backend for validation. status = "OK: \(r.passToken)" } bridge.onFailure = { e in status = "ERROR [\(e.code)] \(e.message)" } Task { @MainActor in // 1. Fetch a one-shot server_token from YOUR backend. let token = await fetchServerTokenFromYourBackend() // 2. Build config and present. let config = CaptchalaConfigBuilder() .appKey("YOUR_APP_KEY") .action("login") .lang("en") // en, zh-CN, zh-TW, ja, ko, ms, vi, id .theme("light") // "light" | "dark" .enableVoice(true) .enableOfflineMode(true) .serverToken(token) .onServerTokenExpired { await fetchServerTokenFromYourBackend() } .build() guard let presenter = topViewController() else { return } CaptchalaClient.shared .initialize(config: config) .setDelegate(bridge) .verify(from: presenter) } } } ``` ::: tip Mac Catalyst und natives macOS Derselbe Swift-Code läuft auf iOS, Mac Catalyst und nativem macOS. Auf Catalyst übergeben Sie einen beliebigen `UIViewController`. Auf nativem macOS verwenden Sie `NSViewController` und rufen `.verify()` ohne Argument auf — das SDK präsentiert sich in seinem eigenen `NSWindow`. ::: ## API-Übersicht | Symbol | Zweck | | --- | --- | | `CaptchalaClient.shared` | Gemeinsames Singleton. Alle Einstiegspunkte hängen daran. | | `CaptchalaConfigBuilder()` | Fluent Builder. Setzt `appKey`, `action`, `lang`, `theme`, `enableVoice`, `enableOfflineMode`, `serverToken`. | | `initialize(config:)` | Wendet die gebaute Konfiguration an. Liefert `self`, sodass `setDelegate` verkettet werden kann. | | `setDelegate(_:)` | Übergeben Sie ein `NSObject`, das `CaptchalaDelegate` implementiert. Das SDK hält eine schwache Referenz. | | `verify(from: presenter)` | Präsentiert das CAPTCHA über dem angegebenen UIViewController (iOS / Catalyst). Das SDK schiebt ein modales Sheet ein. | | `CaptchalaResult` | Wird über `captcha(didSucceedWith:)` zurückgeliefert. Felder: `passToken`, `challengeId`, `ttl`, `isOffline`, `isClientOnly`. | | `onServerTokenExpired { … }` | Asynchrone Closure, die einen frischen `server_token` nachholt, falls der vorherige während der Challenge abläuft. | ## Serverseitige Validierung Leiten Sie `result.passToken` (oder `result.token`) an Ihr Backend weiter und validieren Sie ihn gegen die CaptchaLa-API. Geben Sie `X-App-Secret` niemals im Client-Code preis. ```bash POST https://apiv1.captcha.la/v1/validate X-App-Key: YOUR_APP_KEY X-App-Secret: YOUR_APP_SECRET Content-Type: application/json { "pass_token": "" } ``` Siehe die [API-Referenz](/de/api-reference) für den vollständigen Validierungs-Endpoint und den `X-App-Key` / `X-App-Secret`-Flow. ## Fehlerbehebung - **`Captchala.xcframework` nicht gefunden** Das `.xcframework` und das `.bundle` müssen neben `Example.xcodeproj` liegen. Die Demo referenziert beide über den Dateinamen; halten Sie deren Ort beim Update des SDK stabil. - **Mac Catalyst-Ziel fehlt** Aktivieren Sie in Xcode unter den *Supported Destinations* Ihres Targets *Mac (Mac Catalyst)*. Das Demo-Target wird mit `SUPPORTS_MACCATALYST = YES` ausgeliefert. - **Modal erscheint nicht** Übergeben Sie einen echten `UIViewController` an `verify(from:)`. Die Demo durchläuft `UIApplication.connectedScenes`, um den obersten aktiven Key-Window-Controller zu finden — kopieren Sie diesen Helper, falls Sie nur eine SwiftUI-`View` haben. - **`Info.plist`-Privacy-Strings auf macOS** Aktivieren Sie für Catalyst- / native macOS-Targets die Sandbox-Berechtigung **Outgoing Connections (Client)**. Das SDK führt ausschließlich HTTPS-Aufrufe durch — keinen Mikrofon- oder Kamerazugriff. ## Voraussetzungen - iOS 15+ (Gerät oder Simulator) - macOS 11+ (Big Sur) via Mac Catalyst, macOS 13+ für native Targets - Xcode 15+ - Swift 5.7+ (async/await)