--- title: Flutter SDK --- # Flutter SDK 네이티브 iOS / Android SDK 위에 구축된 Flutter 플러그인. 두 모바일 플랫폼에서 동일한 Dart `CaptchalaClient` 를 사용합니다. Linux / macOS / Windows 데스크톱(임베디드 WebView)도 지원합니다. ## GitHub 데모 ::: tip 📦 [Captcha-La/flutter-demo](https://github.com/Captcha-La/flutter-demo) — 모든 통합 단계가 포함된 실행 가능한 예제. ::: ## 설치 Add the package from pub.dev: ```yaml # pubspec.yaml dependencies: captchala: ^1.3.2 http: ^1.2.0 # used by the demo's token-fetch helpers ``` ```bash flutter pub get flutter run # auto-picks the foreground device # or: flutter run -d ``` For iOS / macOS the first build runs `pod install` automatically. Make sure `ios/Podfile` declares `platform :ios, '13.0'` (or higher). ## 빠른 시작 ```dart import 'package:flutter/material.dart'; import 'package:captchala/captchala.dart'; class LoginScreen extends StatefulWidget { const LoginScreen({super.key}); @override State createState() => _LoginScreenState(); } class _LoginScreenState extends State { String _status = 'Tap to verify'; bool _verifying = false; Future _runVerify() async { setState(() { _verifying = true; _status = 'Fetching server_token...'; }); // 1. Fetch a one-shot server_token from YOUR backend. final initialToken = await fetchServerTokenFromYourBackend(); // 2. Build config from your business action. final config = CaptchalaConfig( appKey: 'YOUR_APP_KEY', action: 'login', // login, register, pay, … lang: 'en', // en, zh-CN, zh-TW, ja, ko, ms, vi, id theme: 'light', // 'light' | 'dark' enableVoice: true, enableOfflineMode: true, maskClosable: false, serverToken: initialToken, ); // 3. Initialize, register callbacks, then call verify(). final client = await CaptchalaClient.instance.initialize(config); client.setCallbacks( onSuccess: (r) async { // Send r.passToken to YOUR backend for validation. if (!mounted) return; setState(() { _status = 'OK: ${r.passToken}'; _verifying = false; }); }, onFail: (e) { if (mounted) setState(() { _status = 'fail: ${e.code}'; _verifying = false; }); }, onError: (e) { if (mounted) setState(() { _status = 'error: ${e.code} ${e.message}'; _verifying = false; }); }, onClose: () { if (mounted && _verifying) setState(() { _status = 'closed'; _verifying = false; }); }, onServerTokenExpired: () => fetchServerTokenFromYourBackend(), ); await client.verify(); } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Column(mainAxisSize: MainAxisSize.min, children: [ ElevatedButton( onPressed: _verifying ? null : _runVerify, child: Text(_verifying ? 'Verifying...' : 'Verify with CAPTCHA'), ), const SizedBox(height: 12), Text(_status, style: const TextStyle(fontFamily: 'monospace')), ]), ), ); } } ``` ## 주요 API | 심볼 | 용도 | | --- | --- | | `CaptchalaClient.instance` | 플러그인의 싱글턴 접근자. | | `CaptchalaConfig(...)` | 평범한 Dart 레코드: `appKey`, `action`, `lang`, `theme`, `enableVoice`, `enableOfflineMode`, `maskClosable`, `serverToken`. | | `await client.initialize(config)` | 설정을 적용하고 동일한 클라이언트 인스턴스를 반환해 `setCallbacks` 를 체이닝할 수 있습니다. | | `setCallbacks(...)` | `onSuccess`, `onFail`, `onError`, `onClose`, `onServerTokenExpired` 콜백을 등록합니다. | | `await client.verify()` | 네이티브 CAPTCHA 뷰를 엽니다(Android: Flutter 위에 Activity, iOS: UIViewController). | | `CaptchalaResult` | `onSuccess` 로 전달되는 객체. 필드: `passToken`, `challengeId`, `ttl`, `isOffline`, `isClientOnly`. | ## 서버 측 검증 `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)를 참고하세요. ## 문제 해결 - **iOS pod install 이 실패함** `ios/Podfile` 에 `platform :ios, '13.0'`(또는 그 이상)을 지정하세요. 플러그인 버전 변경 후 `flutter clean && flutter pub get && cd ios && pod install` 을 실행합니다. - **Android `minSdkVersion` 불일치** `android/app/build.gradle` 의 `minSdkVersion` 을 21 로 올리세요. 그 이하면 네이티브 SDK 컴파일이 거부됩니다. - **콜백이 백그라운드 isolate 에서 실행됨** 콜백 안에서 UI 상태를 바꾸기 전에 항상 `if (mounted)` 로 가드하세요. 데모는 모든 상태 변경 콜백에 이 검사를 둡니다. - **데스크톱 타깃(Linux / Windows / macOS)** Linux 는 GTK3 + WebKitGTK + libcurl 가 필요하고, Windows 는 Edge WebView2 Runtime(Win 10 1809+) 이 필요합니다. macOS 데스크톱은 시스템 WebView 를 자동으로 사용합니다. ## 요구 사항 - Flutter 3.10+ / Dart 3.0+ - Android: `minSdkVersion 21` (Android 5.0+) - iOS: 13.0+ with CocoaPods - Desktop (optional): GTK3 + WebKitGTK on Linux, WebView2 Runtime on Windows 10 1809+