All Products
Search
Document Center

Web Application Firewall:Integrate the Anti-Bot SDK into iOS apps

Last Updated:Mar 31, 2026

The Anti-Bot SDK signs every request from your iOS app. WAF verifies the signature to detect and block bot traffic before it reaches your server.

Prerequisites

Before you begin, ensure that you have:

  • iOS 9.0 or later on your target devices

  • App Protection purchased and enabled. See Procedure to enable App Protection

  • The iOS SDK package (AliTigerTally_IDFA.framework or AliTigerTally_NOIDFA.framework). Submit a ticket to get the SDK

  • Your app key. To get it, log on to the WAF console, go to Protection Configurations > Website Protection, open the Bot Management tab, turn on App Protection, and click Obtain and Copy Appkey

Each Alibaba Cloud account has one app key, shared across all domain names in your WAF instance. The same app key works for both Android and iOS apps.
App Protection

App key example:

****OpKLvM6zliu6KopyHIhmneb_****u4ekci2W8i6F9vrgpEezqAzEzj2ANrVUhvAXMwYzgY_****vc51aEQlRovkRoUhRlVsf4IzO9dZp6nN_****Wz8pk2TDLuMo4pVIQvGaxH3vrsnSQiK****

Choose an SDK version

The SDK comes in two versions depending on whether your app uses the Identifier for Advertisers (IDFA):

VersionFramework fileUse when
IDFAAliTigerTally_IDFA.frameworkYour app uses IDFA
Non-IDFAAliTigerTally_NOIDFA.frameworkYour app does not use IDFA

How it works

  1. The SDK signs the request body using vmpSign and returns a signature token (wToken).

  2. Your app attaches wToken to the HTTP request header and sends the request.

  3. WAF parses wToken on every inbound request, blocks malicious traffic, and forwards legitimate requests to your server.

Sign requests at business-critical events such as login, payment submission, or any action that warrants protection.

Integrate the SDK

Step 1: Set up the Xcode project

Open your iOS project in Xcode and copy the SDK framework into the project directory.

Step 2: Add dependency libraries

Add the following libraries to your target:

LibraryNon-IDFA versionIDFA version
libc++.tbdRequiredRequired
CoreTelephony.frameworkRequiredRequired
libresolv.9.tbdRequiredRequired
AdSupport.frameworkNot requiredRequired

Step 3: Add the -ObjC linker flag

In Build Settings, add -ObjC to Other Linker Flags.

Step 4: Import the SDK header

Objective-C — add the import to any source file that calls the SDK:

// Non-IDFA version
#import <AliTigerTally_NOIDFA/AliTigerTally.h>

// IDFA version
#import <AliTigerTally_IDFA/AliTigerTally.h>

Swift — create a bridging header file and add the import:

#ifndef TigerTally_sdk_Swift_h
#define TigerTally_sdk_Swift_h

// Non-IDFA version
#import <AliTigerTally_NOIDFA/AliTigerTally.h>
// IDFA version
#import <AliTigerTally_IDFA/AliTigerTally.h>

#endif /* TigerTally_sdk_Swift_h */

Then set the bridging header path in Build Settings > Objective-C Bridging Header.

Step 5: Set a user ID (optional)

Call setAccount to associate a user ID with SDK requests. This lets you build finer-grained WAF protection policies. For guest users, skip this call and go directly to initialize.

Syntax:

-(void)setAccount:(NSString*)account
ParameterTypeDescription
accountNSString*User ID. Use a masked value rather than a raw identifier.

Objective-C:

// Use a masked user ID
[[AliTigerTally sharedInstance] setAccount:@"testAccount"];

Swift:

AliTigerTally.sharedInstance().setAccount("testAccount")

Step 6: Initialize the SDK

Call initialize with your app key to start the SDK and collect device information. Call it again any time you need to refresh device information.

Syntax:

-(bool)initialize:(NSString*)appKey
ParameterTypeDescription
appKeyNSString*Your SDK authentication key.

Returns true on success, false on failure.

Objective-C:

NSString *appKey = @"****OpKLvM6zliu6KopyHIhmneb_****u4ekci2W8i6F9vrgpEezqAzEzj2ANrVUhvAXMwYzgY_****vc51aEQlRovkRoUhRlVsf4IzO9dZp6nN_****Wz8pk2TDLuMo4pVIQvGaxH3vrsnSQiK****";
if ([[AliTigerTally sharedInstance] initialize:appKey]) {
    NSLog(@"Initialization successful.");
} else {
    NSLog(@"Initialization failed.");
}

Swift:

let binit = AliTigerTally.sharedInstance().initialize("****OpKLvM6zliu6KopyHIhmneb_****u4ekci2W8i6F9vrgpEezqAzEzj2ANrVUhvAXMwYzgY_****vc51aEQlRovkRoUhRlVsf4IzO9dZp6nN_****Wz8pk2TDLuMo4pVIQvGaxH3vrsnSQiK****")
if binit {
    NSLog("Initialization successful.")
} else {
    NSLog("Initialization failed.")
}

Step 7: Sign requests

Call vmpSign to generate a signature token for the request body.

Syntax:

-(NSString*)vmpSign:(NSData*)inputBody
ParameterTypeDescription
inputBodyNSData*The request body to sign.

Returns a signature string (NSString*) on success. The signature is referred to as wToken.

Error return values:

Return valueCauseFix
you must call initializeinitialize was not calledCall initialize before vmpSign
you must input bodyinputBody was not providedPass the request body when calling vmpSign
NULLInitialization not completeCall vmpSign again

Objective-C:

if (![[AliTigerTally sharedInstance] initialize:@"****OpKLvM6zliu6KopyHIhmneb_****u4ekci2W8i6F9vrgpEezqAzEzj2ANrVUhvAXMwYzgY_****vc51aEQlRovkRoUhRlVsf4IzO9dZp6nN_****Wz8pk2TDLuMo4pVIQvGaxH3vrsnSQiK****"]) {
    NSLog(@"Initialization failed.");
    return;
}
NSString *signBody = @"hello";
NSString *wToken = [[AliTigerTally sharedInstance] vmpSign:[signBody dataUsingEncoding:NSUTF8StringEncoding]];
NSLog(@"wToken: %@", wToken);

Swift:

if !AliTigerTally.sharedInstance().initialize("****OpKLvM6zliu6KopyHIhmneb_****u4ekci2W8i6F9vrgpEezqAzEzj2ANrVUhvAXMwYzgY_****vc51aEQlRovkRoUhRlVsf4IzO9dZp6nN_****Wz8pk2TDLuMo4pVIQvGaxH3vrsnSQiK****") {
    NSLog("Initialization failed.")
    return
}
let signBody = "hello"
let token = AliTigerTally.sharedInstance().vmpSign(signData)
NSLog(token)

Step 8: Send the signed request

Add wToken to the HTTP request header and send the request.

Objective-C:

NSURL *url = [NSURL URLWithString:@"https://xxxxxx/test?id=123"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                   timeoutInterval:10];
[request setValue:wToken forHTTPHeaderField:@"wToken"];
request.HTTPMethod = @"post";
request.HTTPBody = [signBody dataUsingEncoding:NSUTF8StringEncoding];

NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession]
    dataTaskWithRequest:request
      completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
          if (error) {
              NSLog(@"Request failed: %@", error);
          } else {
              NSLog(@"Request sent.");
          }
      }];
[dataTask resume];

Swift:

guard let url = URL(string: "https://xxxxxx/test?id=123") else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue(token, forHTTPHeaderField: "wToken")

URLSession.shared.dataTask(with: request) { data, response, error in
    if let error = error {
        print("Request failed: \(error)")
    } else {
        print("Request sent.")
    }
}.resume()

(Optional) Test with a sample project

Before integrating into your production app, create a test iOS project in Xcode to verify the integration steps.

The following figure shows a sample test project named TigerTally_sdk_test.

Test project