Skip to content

SDK iOS / macOS

SDK para plataformas Apple, iOS 15+ y macOS 11+ (Big Sur) mediante Mac Catalyst, distribuido como un .xcframework más un .bundle de recursos localizados. Drop-in para proyectos SwiftUI, UIKit y AppKit.

Demo en GitHub

📦

Captcha-La/iosmacos-demo — ejemplo completo y ejecutable con cada paso de integración.

Instalación

Añade CaptchaLa a tu Podfile (CocoaPods 1.10+):

ruby
# Podfile
platform :ios, '13.0'

target 'YourApp' do
  use_frameworks!
  pod 'Captchala', '~> 1.0.2'
end
bash
pod install

O bien, si prefieres la integración manual:

Descarga la última versión de iOS desde el panel de CaptchaLa. El archivo contiene:

  • Captchala.xcframework — el SDK compilado
  • Captchala.bundle — recursos localizados

Coloca ambos junto a tu .xcodeproj. El proyecto de la demo los referencia por nombre de fichero; no hace falta enlazado manual adicional siempre que su ubicación permanezca estable.

Para la integración manual, descarga el xcframework directamente: dash.captcha.la/downloads

text
YourApp/
├── YourApp.xcodeproj
├── YourApp/
├── Captchala.xcframework
└── Captchala.bundle

Abre el proyecto y ejecútalo en el simulador, en un dispositivo o en My Mac (Mac Catalyst):

bash
open YourApp.xcodeproj
# Cmd-R in Xcode

Inicio rápido

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)
        }
    }
}

Mac Catalyst y macOS nativo

El mismo código Swift se ejecuta en iOS, Mac Catalyst y macOS nativo. En Catalyst pasa cualquier UIViewController. En macOS nativo usa NSViewController y llama a .verify() sin argumentos — el SDK se presenta en su propio NSWindow.

Superficie de la API

SímboloPropósito
CaptchalaClient.sharedSingleton compartido. Todos los puntos de entrada dependen de él.
CaptchalaConfigBuilder()Builder fluido. Configura appKey, action, lang, theme, enableVoice, enableOfflineMode, serverToken.
initialize(config:)Aplica la configuración construida. Devuelve self para encadenar setDelegate.
setDelegate(_:)Proporciona un NSObject que cumpla CaptchalaDelegate. El SDK mantiene una referencia débil.
verify(from: presenter)Presenta el CAPTCHA sobre el UIViewController indicado (iOS / Catalyst). El SDK abre una hoja modal.
CaptchalaResultDevuelto vía captcha(didSucceedWith:). Campos: passToken, challengeId, ttl, isOffline, isClientOnly.
onServerTokenExpired { … }Closure asíncrono que vuelve a obtener un server_token nuevo si el anterior caduca a mitad del desafío.

Validación en el servidor

Reenvía result.passToken (o result.token) a tu backend y valídalo contra la API de CaptchaLa. Nunca expongas X-App-Secret en el código del cliente.

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": "<result.passToken>", "client_ip": "<end-user IP>" }

Consulta la Referencia de la API para el endpoint de validación completo y el flujo de X-App-Key / X-App-Secret.

Solución de problemas

  • Captchala.xcframework no encontrado
    El .xcframework y el .bundle deben estar junto a Example.xcodeproj. La demo los referencia por nombre de fichero; mantén su ubicación estable al actualizar el SDK.

  • Destino Mac Catalyst ausente
    En Xcode, activa Mac (Mac Catalyst) en Supported Destinations de tu target. La demo se entrega con SUPPORTS_MACCATALYST = YES.

  • El modal no aparece
    Pasa un UIViewController real a verify(from:). La demo recorre UIApplication.connectedScenes para encontrar el controlador de la key-window activa más superior — copia ese helper si solo tienes una View de SwiftUI.

  • Cadenas de privacidad de Info.plist en macOS
    Para los targets Catalyst / macOS nativo activa la capacidad sandbox Outgoing Connections (Client). El SDK solo realiza llamadas HTTPS, sin acceso a micrófono ni cámara.

Requisitos

  • iOS 15+ (dispositivo o simulador)
  • macOS 11+ (Big Sur) vía Mac Catalyst, macOS 13+ para targets nativos
  • Xcode 15+
  • Swift 5.7+ (async/await)

MIT-licensed examples · CaptchaLa is operated independently