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

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