iOS Integration
Overview
This document elaborates on the integration steps of the EdgeOne client attestation SDK in an iOS project, including SDK support for importing, permission configuration, initialization, engine startup, challenge handling, and token usage in API requests.
Integration Steps
Note:
Before starting integration, ensure you have read and understood the Mobile Terminal Integration Overview to learn about the basic attestation process on mobile.
1. Adding EdgeOne SDK to Your Project
Integrating the EdgeOne client attestation SDK into your iOS project is the first step. You can introduce the SDK through CocoaPods. Add the following content to your
Podfile:pod 'ClientAttestation', :podspec => './SDK'
Then run the following command:
pod install
2. Configuring Info.Plist Permission
The SDK requires basic network access during the attestation process. Please add the following permission declaration in your project's
Info.plist file to ensure the SDK can perform normal network communication:<key>NSAppTransportSecurity</key><dict><key>NSAllowsArbitraryLoads</key><true/></dict>If your application needs to access the Internet, please ensure this permission is declared.<key>NSInternetPermission</key><true/>
Note: The
NSAllowsArbitraryLoads setting allows application loading of non-HTTPS resources. In a production environment, strongly recommend configuring ATS exceptions to only allow necessary domains via HTTPS to enhance security.3. Initializing the SDK
Before using any attestation feature, you need to initialize the EdgeOne SDK with your service domain and optional log level. This operation is typically executed once in your
AppDelegate or at application startup.import ClientAttestationfunc application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {// SDK initializationlet baseUrl = "www.example.com" // set to business domainlet basOptions = TCBasOptions()basOptions.baseUrl = baseUrlbasOptions.logLevel = LOG_LEVEL_DEBUG // Optional, set log levelTCBas.initialize(with: basOptions)return true}
Parameter description:
baseUrl: Your EdgeOne service domain name, such as www.example.com.logLevel: Optional parameter used to control the SDK log output level. Optional values include:LOG_LEVEL_NONE: Disable logs (default)LOG_LEVEL_DEBUG: Enable logs at debug level and aboveLOG_LEVEL_INFO: Enable logs at info level and aboveLOG_LEVEL_WARN: Enable logs at warning level and aboveLOG_LEVEL_ERROR: Enable logs at error level and above4. Starting the Attestation Engine
After the SDK initialization is completed, you need to start the client attestation engine so that the SDK can begin acquisition and manage attestation tokens. This operation starts the necessary background process inside the SDK.
// Start the client attestation engine[[ClientAttestation sharedInstance] start];
Note: After the attestation engine starts, the SDK will be ready to handle attestation challenges and manage attestation tokens.
5. Execute Client Attestation Challenge
The attestation challenge is a key step to obtain the attestation token. This process involves retrieving the challenge ID and passing it into the SDK. The SDK will display the necessary UI (such as showing the Captcha in
WKWebView) as needed and compute the attestation token. This is done via the attestWithParams() method provided by the SDK.// attestId// Get from console when actively initiating a challenge// Retrieve from the 'EO-Attest-Challenge' header field in the http response when passively triggering a ChallengeNSString *attestId = @"your-attestId";AttestParams *params = [[AttestParams alloc] init];params.attestId = attestId;params.webView = webView; // WebView used for Captcha displayparams.reqTimeoutMillis = 60000; // Optional, request timeout[[ClientAttestation sharedInstance] attestWithParams:paramscallback:self];// Implement the AttestCallbackDelegate protocol#pragma mark - AttestCallbackDelegate- (void)onSuccess:(NSString *)token {// Return the risk invoice, place the invoice in the header field 'EO-Attest-Token' of the http request}- (void)onError:(NSError *)error {// Error message returned}
Parameter description:
attestId: Configure the challenge ID, get from console or return in request result.webView: optional parameter, a WKWebView instance. When the authenticator requires user interaction (such as Captcha), you must provide this parameter. If UI interaction is not required, the WKWebView can be hidden.reqTimeoutMillis: Optional parameter to set request timeout in milliseconds. Default is 60 seconds.6. Include an Attestation Token in API Request
When your iOS app initiates an API request to a backend service protected by EdgeOne, must include an attestation token in the request header. You can call the
getAttestationToken() method provided by the SDK to readily obtain the current valid attestation token.Note:
After each successful call to
attestWithParams(), the SDK generates or updates the attestation token. Before attaching the token to request headers, be sure to call getAttestationToken() again to get the latest token. Each time you need to use token data, please retrieve new token data. Do not save or reuse the token data returned by getAttestationToken().// Get client attestation invoiceNSString *attestToken = [[ClientAttestation sharedInstance] getAttestationToken];// Example: Add the token to your network request header// Assuming you are using URLSession or another network libraryif (attestToken) {// Your request objectNSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://your-backend-api.com/data"]];[request setValue:attestToken forHTTPHeaderField:@"EO-Attest-Token"];// Continue sending the request}
Note: Ensure this token is included in each API request requiring attestation. The SDK will automatically manage the token lifecycle. You just need to get the latest token before sending a request.
7. Handling Server Response and Challenges
When your backend service (protected by EdgeOne) receives a client request, it checks if the request contains a valid attestation token. If attestation is required but no valid token is provided, the server will return HTTP status code 428, indicating the client needs additional attestation. This is a key link in iOS client integration that requires proactive adaptation by developers.
Your iOS application needs to implement a mechanism to capture and handle these HTTP 428 responses. For the detailed process, please refer to reobtaining the attestation token or renewing an expired attestation token (handling HTTP 428 challenges).
Here is a simplified example of handling HTTP 428 challenges:
// Assume your network request processing logic- (void)sendAPIRequest:(NSMutableURLRequest *)request {NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {if (error) {NSLog(@"network error: %@", error.localizedDescription);return;}NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;if (httpResponse.statusCode == 428) {// Received 428 challenge, extract challenge IDNSString *challengeId = httpResponse.allHeaderFields[@"EO-Attest-Challenge"];if (challengeId) {NSLog(@"Received 428 challenge, challenge ID: %@", challengeId);// Execute attestation challenge// Create or reuse a WKWebView instance as neededWKWebView *webView = [[WKWebView alloc] init];AttestParams *attestParams = [[AttestParams alloc] init];attestParams.attestId = challengeId;attestParams.webView = webView;[[ClientAttestation sharedInstance] attestWithParams:attestParams callback:self];// Note: Need to process the AttestCallbackDelegate callback and resend the request in onSuccess} else {NSLog(@"428 EO-Attest-Challenge header not found in response");}} else if (httpResponse.statusCode == 200) {NSLog(@"Request succeeded.");// Process business data} else {NSLog(@"Request failed, status code: %ld", (long)httpResponse.statusCode);// fix other errors}}];[task resume];}// Example call// NSMutableURLRequest *initialRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://your-backend-api.com/protected-data"]];// [self sendAPIRequest:initialRequest];// Resend the request in the onSuccess method of AttestCallbackDelegate#pragma mark - AttestCallbackDelegate- (void)onSuccess:(NSString *)token {NSLog(@"Challenge Success, obtain new token: %@", token);// Resend the original request with the new token// Need to get the previous request object and resend// For example:// NSMutableURLRequest *retryRequest = [self.lastFailedRequest mutableCopy]; // Assume you saved the last failed request// [retryRequest setValue:token forHTTPHeaderField:@"EO-Attest-Token"];// [self sendAPIRequest:retryRequest];}- (void)onError:(NSError *)error {NSLog(@"attestation challenge failure: %@", error.localizedDescription);}
8. (Optional) Using WKWebView for Interactive Attestation (And JS Attestation)
In some client attestation scenarios, the authenticator may require user interaction (e.g., interactive Captcha) or execute compute-intensive tasks (e.g., Proof of Work encryption). At this point, EdgeOne SDK requires specific runtime environment support. On mobile platforms,
WKWebView (iOS platform) is the key component to implement these features.When the authenticator needs to render an interactive CAPTCHA or run a JavaScript-based Proof-of-Work encryption challenge, the SDK requires a
WKWebView instance to be provided when calling the attestWithParams() method. This means developers must allocate a WKWebView instance in advance in the application and pass it as an argument to the SDK when calling the attestation API.Interactive Attestation Scenario
Some authenticators (such as TC-CAPTCHA using embedded or pop-up interaction settings) require a
WKWebView instance to render their interactive interface. The WKWebView instance will display the CAPTCHA page within the application, so it must be preset to ensure correct display.Embedded Interactive Attestation: The CAPTCHA interface is displayed as a fixed block on the device screen. To ensure correct UI display without affecting user experience, developers must preset the rendering window's size, layering sequence, and alignment mode. Please note, the embedded attestation GUI does not scale with the screen view. For example, TC-CAPTCHA embedded mode recommends reserving at least 300x230 pixel space to achieve the best rendering effect and user interaction experience.
Pop-up Interactive Attestation: The CAPTCHA interface appears as a floating window on the device screen when attestation is triggered. Similar to embedded attestation, the size, layering sequence, and alignment mode of the rendering window must be preset. The key feature of pop-up attestation is that when the screen view is below a specific threshold, the pop-up attestation GUI will automatically resize to adapt to different screen sizes. For example, TC-CAPTCHA pop-up mode has an initial rendering block size of 360x360 pixels.
JavaScript-Based Attestation Scenario
Some authenticators (such as TC-CAPTCHA in silent mode) require a
WKWebView instance as the JavaScript runtime environment, primarily for executing encrypted Proof of Work (PoW) challenges. In this case, the WKWebView instance provides only a JavaScript execution sandbox, with no need to visibly render any UI. Therefore, the passed-in WKWebView instance does not need to be visible, and the SDK will not use it for UI rendering.
- Overview
- Integration Steps
- 1. Adding EdgeOne SDK to Your Project
- 2. Configuring Info.Plist Permission
- 3. Initializing the SDK
- 4. Starting the Attestation Engine
- 5. Execute Client Attestation Challenge
- 6. Include an Attestation Token in API Request
- 7. Handling Server Response and Challenges
- 8. (Optional) Using WKWebView for Interactive Attestation (And JS Attestation)