--- title: iOS / macOS SDK --- # iOS / macOS SDK Apple 平台 SDK,支持 **iOS 15+** 与基于 Mac Catalyst 的 **macOS 11+(Big Sur)**,以 `.xcframework` + 本地化资源 `.bundle` 形式发布。SwiftUI / UIKit / AppKit 项目均可直接接入。 ## GitHub 上的示例 ::: tip 📦 [Captcha-La/iosmacos-demo](https://github.com/Captcha-La/iosmacos-demo) — 完整可运行示例,包含所有集成步骤。 ::: ## 安装 在 `Podfile` 里添加 CaptchaLa(CocoaPods 1.10+): ```ruby # Podfile platform :ios, '13.0' target 'YourApp' do use_frameworks! pod 'Captchala', '~> 1.0.2' end ``` ```bash pod install ``` 如果你更想手动集成: 从 [CaptchaLa 控制台](https://dash.captcha.la) 下载最新的 iOS 发布包。压缩包包含: - `Captchala.xcframework` —— 编译后的 SDK - `Captchala.bundle` —— 本地化资源 将两者放在 `.xcodeproj` 同级目录下。demo 工程通过文件名引用它们,只要保持位置稳定,无需手动链接。 手动集成请直接下载 xcframework:[dash.captcha.la/downloads](https://dash.captcha.la/downloads) ```text YourApp/ ├── YourApp.xcodeproj ├── YourApp/ ├── Captchala.xcframework └── Captchala.bundle ``` 打开工程,在模拟器、真机或 **My Mac (Mac Catalyst)** 中运行: ```bash open YourApp.xcodeproj # 在 Xcode 中按 Cmd-R ``` ## 快速开始 ```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 与原生 macOS 完全一样的 Swift 代码可以同时跑在 iOS、Mac Catalyst 和原生 macOS 上。Catalyst 下传入任意 `UIViewController`;原生 macOS 下用 `NSViewController`,并以不带参数的方式调用 `.verify()` —— SDK 会在自己的 `NSWindow` 中展示。 ::: ## API 一览 | 符号 | 用途 | | --- | --- | | `CaptchalaClient.shared` | 共享单例,所有入口都通过它访问。 | | `CaptchalaConfigBuilder()` | 链式 Builder,用于设置 `appKey`、`action`、`lang`、`theme`、`enableVoice`、`enableOfflineMode`、`serverToken`。 | | `initialize(config:)` | 应用构建好的配置。返回 `self`,便于链式调用 `setDelegate`。 | | `setDelegate(_:)` | 传入实现了 `CaptchalaDelegate` 的 `NSObject`。SDK 持弱引用。 | | `verify(from: presenter)` | 在指定的 UIViewController 上呈现验证码(iOS / Catalyst),SDK 弹出 modal sheet。 | | `CaptchalaResult` | 通过 `captcha(didSucceedWith:)` 回调返回。字段:`passToken`、`challengeId`、`ttl`、`isOffline`、`isClientOnly`。 | | `onServerTokenExpired { … }` | 异步闭包,当当前 `server_token` 在挑战过程中过期时,自动获取新的 token。 | ## 服务端校验 把 `result.passToken`(或 `result.token`)发到你的后端,再调用 CaptchaLa API 校验。**绝不要在客户端代码中暴露 `X-App-Secret`**。 ```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": "" } ``` 完整校验接口及 `X-App-Key` / `X-App-Secret` 流程见 [API 参考](../api-reference)。 ## 常见问题 - **找不到 `Captchala.xcframework`** `.xcframework` 和 `.bundle` 必须与 `Example.xcodeproj` 同级。demo 通过文件名引用它们,更新 SDK 时保持位置不变即可。 - **找不到 Mac Catalyst destination** 在 Xcode 中,于 target 的 *Supported Destinations* 中勾选 *Mac (Mac Catalyst)*。demo target 默认 `SUPPORTS_MACCATALYST = YES`。 - **modal 没有弹出** `verify(from:)` 必须传入真实的 `UIViewController`。demo 中通过遍历 `UIApplication.connectedScenes` 找最顶层的 key-window controller,如果你只有 SwiftUI `View`,复制这段 helper 即可。 - **macOS 上需要 `Info.plist` 隐私描述** 对 Catalyst / 原生 macOS target,开启 **Outgoing Connections (Client)** 沙箱权限。SDK 仅发起 HTTPS 请求,不访问麦克风或摄像头。 ## 环境要求 - iOS 15+(真机或模拟器) - macOS 11+(Big Sur)通过 Mac Catalyst,原生 macOS 目标需 macOS 13+ - Xcode 15+ - Swift 5.7+(async/await)