GeeTest captcha iOS SDK supports for native iOS. The SDK doesn’t contain any third-party library.

Development environment

Item Description
Target iOS 9+
Development environment Xcode 12+
Dependency Webkit.framework
Third-party dependency None


Item Description
Data communication flow chart Data communication flow chart, Interaction flow chart
SDK API reference gt3-ios-docs or check the header files
Error code Error Code



Mannualy download SDK & Demo

Please click the link below to download the latest SDK (in .zip format).

Get SDK via CocoaPods

Please add the following to the file named Podfile in your workspace

pod 'GT3Captcha-iOS'

Get SDK via Swift Package Manager

Here are the details for your reference: https://github.com/GeeTeam/gt3-spm-repo

Import SDK

  1. If you add the SDK manually, please drag and drop the GT3Captcha.framework into the project and select Copy items if needed.


    Please use Linked Frameworks and Libraries to import the framework。After you have added GT3Captcha.framework into the project, please check if .framework has been successfully added in PROJECT -> Build Phases -> Linked Frameworks and Libraries.


  2. For the Category in static libraries, please add -ObjC flag via Build Settings->Other Linker Flags for the corresponding target. Please add -ObjC flag. If it doesn’t work, please add -all_load.


  3. SDK version 0.9.0 and later needs to add GT3Captcha.Bundle to project. Drag and drop GT3Captcha.Bundle from the .zip to the project.

Apple has announced a new privacy policy for applications (including SDK) at WWDC23, and there is a separate session on this topic titled Get started with privacy manifests - WWDC23 - Videos - Apple Developer. On July 27th, Apple released a news article stating that starting in the fall of 2023, if a newly uploaded application uses relevant APIs that do not provide a privacy manifest, you will receive an email notification. Starting in the spring of 2024, privacy manifests will become a mandatory requirement. The APIs involved and the reasons for their use can be found in Describing use of required reason API | Apple Developer Documentation. If the reason for use is not listed, you can directly submit the specific usage reason. For instructions on how to create a new privacy manifest, please refer to Privacy manifest files | Apple Developer Documentation.

It is hereby stated that GeeTest captcha of the iOS SDK uses some functions to retrieve disk space for writing logs, involving the NSPrivacyAccessedAPICategoryDiskSpace.


Please firstly integrate server SDK, configure the id and key (get from GeeTest dashboard) and implement API1 and API2 in the initial method.

To use the SDK, please firstly finish the following steps.

  1. Initialize captcha
  2. Start captcha
  3. Get the verification result
  4. Handle errors

There are two styles of captcha button integration. Please choose one of them.

  1. Use GT3CaptchaManager and bind with users events (Bind GeeTest captcha to your custom button, i.e. invisible captcha)
  2. Use GT3CaptchaButton (Integrate with GeeTest captcha button)

Whatever integration method is used, the project must conform to <GTCaptchaManagerDelegate> protocol to process verification results and the possible returned errors.

The following example shows how to integrate:

Compile and run your project

Compile your project and experience GeeTest captcha.

Visual presentation

  1. Bind GeeTest captcha to a custom button


  2. Integrate with GeeTest captcha button


Code examples

Initialize captcha and start captcha

Import static library GT3Captcha.framework in header files

#import <GT3Captcha/GT3Captcha.h>

Bind GeeTest captcha to a custom button

The following example bind the captcha with UIButton

  1. Initialize captcha
    Instantiate CAPTCHA manager GTCaptchaManager. Call the register method in GTCaptchaManager to get register data.

    - (GT3CaptchaManager *)manager {
    if (!_manager) {
    _manager = [[GT3CaptchaManager alloc] initWithAPI1:api_1 API2:api_2 timeout:5.0];
    _manager.delegate = self;

    return _manager;

    - (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];

    if (self) {
    [self.manager registerCaptcha:nil];
    return self;
  1. Start captcha

    After finished with captcha initialization and register, call the following method to activate captcha.

    [self.manager startGTCaptchaWithAnimated:YES];

Integrate with GeeTest captcha button (use GT3CaptchaButton in SDK)

The example integrate captcha with ViewController

  1. Initialize captcha
    Initial the instance of GTCaptchaManager and assign this instance to GTCaptchaButton.Then, add the GTCaptchaButton to [ViewController view].

    - (void)viewWillAppear:(BOOL)animated {
    [self createCaptcha];

    - (void)createCaptcha {
    // Create a new instance of `GT3CaptchaManager`
    GT3CaptchaManager *captchaManager = [[GT3CaptchaManager alloc] initWithAPI1:<--Your api1--> API2:<--Your api2--> timeout:5.0];
    captchaManager.delegate = self;

    //debug mode
    // [captchaManager enableDebugMode:YES];

    // Create a new instance of `GT3CaptchaButton`. And add it to the view which you want.
    GT3CaptchaButton *captchaButton = [[GT3CaptchaButton alloc] initWithFrame:CGRectMake(0, 0, 300, 44) captchaManager:captchaManager];
    captchaButton.center = self.view.center;
    //Recommend to start the captcha directly
    [captchaButton registerCaptcha:nil];
    [self.view addSubview:captchaButton];
  1. Start captcha

    Click the captcha button or use the following method to activate captcha.

    [captchaButton startCaptcha];

Get the verification result

Only after finishing the secondary verification, the verification process is complete. Please conform to GTCaptchaManagerDelegate protocol and process the following delegate methods.

- (void)gtCaptcha:(GT3CaptchaManager *)manager didReceiveSecondaryCaptchaData:(NSData *)data response:(NSURLResponse *)response error:(GT3Error *)error decisionHandler:(void (^)(GT3SecondaryCaptchaPolicy))decisionHandler {
if (!error) {
//Handle your verification result
NSLog(@"\nsession ID: %@,\ndata: %@", [manager getCookieValue:@"msid"], [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
//If succeeded, please call decisionHandler(GT3SecondaryCaptchaPolicyAllow)
//If failed, please call decisionHandler(GT3SecondaryCaptchaPolicyForbidden)
else {
// Error occurred during the secondary verification
NSLog(@"validate error: %ld, %@", (long)error.code, error.localizedDescription);

Handle errors

During the verification process, there might be some errors. Please conform to GTCaptchaManagerDelegate protocol and handle the errors with the following delegate methods.

- (void)gtCaptcha:(GTCaptchaManager *)manager errorHandler:(GTError *)error {
//Handle errors
NSLog(@"error: %@", error.localizedDescription);

Please check the link for the error codes. GT3Error

Optional captcha Delegate Methods

Modify API1 request

Since some companies might require authentication or custom parameters, you could use the following delegate methods to custom the API1 request.

- (void)gtCaptcha:(GT3CaptchaManager *)manager willSendRequestAPI1:(NSURLRequest *)originalRequest withReplacedHandler:(void (^)(NSURLRequest *))replacedHandler {
NSMutableURLRequest *mRequest = [originalRequest mutableCopy];

TO-DO. Handle mRequest by yourself


Please check AsyncButton file in the following link for custom API1 & API2 request example. Code Example

Modify API2 request

Since some companies might require authentication or custom parameters, you could use the following delegate methods to custom the API2 request.

- (void)gtCaptcha:(GT3CaptchaManager *)manager willSendSecondaryCaptchaRequest:(NSURLRequest *)originalRequest withReplacedRequest:(void (^)(NSMutableURLRequest *))replacedRequest {
/// Modify the secondary verification request if needed
NSMutableURLRequest *mReuqest = [originalRequest mutableCopy];
NSData *secodaryData = mReuqest.HTTPBody;
NSLog(@"data: %@", [[NSString alloc] initWithData:secodaryData encoding:NSUTF8StringEncoding]);

TO-DO, Process secodaryData

// NSData *newData = [secodaryData handlerYourData]
// mReuqest.HTTPMethod = newData;

Please check AsyncButton file in the following link for custom API1 & API2 request example. Code Example

Get verification parameters

To get the verification parameters, you can use the following delegate methods.

- (void)gtCaptcha:(GT3CaptchaManager *)manager didReceiveCaptchaCode:(NSString *)code result:(NSDictionary *)result message:(NSString *)message {
NSLog(@"result: %@", result);

Disable the default API1 request

Please refer to the following example to disable the default API1 request.

- (BOOL)shouldUseDefaultRegisterAPI:(GT3CaptchaManager *)manager {
return NO;

Since the API1 request has been disabled, please configure captcha parameters manually, otherwise you cannot start captcha.

// dict contains gt, challenge, success, etc.
NSString *geetest_id = [dict objectForKey:@"gt"];
NSString *geetest_challenge = [dict objectForKey:@"challenge"];
NSNumber *geetest_success = [dict objectForKey:@"success"];
// Don't invoke this method duplicated
[self.manager configureGTest:geetest_id challenge:geetest_challenge success:geetest_success withAPI2:api_2];

Disable the default API2 request

Please refer to the following example to disable the default API2 request.

- (BOOL)shouldUseDefaultSecondaryValidate:(GT3CaptchaManager *)manager {
return NO;


After the API2 request has been disabled, the verification result prompt in the captcha button depends on the code in gtCaptcha:didReceiveCaptchaCode:result:message:. The @"1" refers to verification success.

Other integrate method

After 0.13.0, developer could use GT3AsyncTaskProtocol and registerCaptchaWithCustomAsyncTask:completion: to complete the process of API1 and API2 by custom.

If use registerCaptchaWithCustomAsyncTask:completion:, delegate methods below couldn’t be invoked:

  • shouldUseDefaultRegisterAPI:
  • gtCaptcha:willSendRequestAPI1:withReplacedHandler:
  • gtCaptcha:didReceiveDataFromAPI1:withError:
  • shouldUseDefaultSecondaryValidate:
  • gtCaptcha:willSendSecondaryCaptchaRequest:withReplacedRequest:

Please check AsyncTaskButton.m and DemoAyncTask.m for more detail. Example project

Other APIs and Swift example project

Please check the API reference for further details.

Download Example & Docs

Please refer to the example project for more example-files. More Swift example could be find in DefaultDemoViewController.swift and AsyncTaskViewController.swift.

Was this helpful?