iOS

Integrated Requirement

Compliance Explanation

Please note that when integrating SDK products provided by the TrustDecision in the APP of your company:

1.1 According to the user's information protection regulations, before your users start the App for the first time and start collecting information, your company should fully inform the user of the purpose, method, and scope of collecting, using, and sharing the user's personal information with a third party through an interactive interface or design (such as a pop-up window of the privacy policy), and obtain the express consent of the end user.

1.2 To provide business security and risk control services to your company, the TrustDecision SDK will collect, process, and use the identification information(IMEI/IDFA), AndroidID, IMSI, MEID, MAC address, SIM card serial number, device type, device model, system type, geographical location, login IP address, application list, running process, sensor information(light sensor, gravity sensor, magnetic field sensor, acceleration sensor, gyroscope sensor) and other device information of the user's device. To ensure compliance with your use of related services, the aforementioned privacy policy should cover the authorization of TrustDecision SDK to provide services and collect, process, and use relevant information. The following terms are for your reference. The specific expression can be determined by your company according to the overall framework and content of your privacy agreement:

TrustDecision SDK: For business security and risk control, our company uses the TrustDecision SDK. The SDK needs to obtain the information of your devices, such as (IMEI/IDFA), AndroidID, IMSI, MAC address, SIM card serial number, device type, device model, system type, geographic location, login IP address, application list, running process, sensor information(light sensor, gravity sensor, magnetic field sensor, acceleration sensor, gyroscope sensor) and other related device information, for fraud risk identification.

Privacy Protocol: https://www.trustdecision.com/legal/privacy-policy

Environment

ItemsDescription
Supported System VersionsiOS9.0+
Supporting architecturearmv7, arm64, x86_64

Integrate Steps

CocoaPods

  • Added pod 'TrustDecisionPro', '4.2.6.5' in the corresponding target in the Podfile
  • Added pod 'TrustDecisionLiveness', '2.2.1' in the corresponding target in the Podfile
  • Execute the pod install --repo-update command in the folder where the Podfile is located. (M1 series mac computers need to execute arch -x86_64 pod install --repo-update command)

SDK Structure

files in Pods/TrustDecisionPro directory:

  • TDMobRisk.framework(TrustDecision SDK, is a static library type)
  • TDCorePlugin.framework (TrustDecision plugin, is an Embed dynamic library type)

files in Pods/TrustDecisionLiveness directory:

  • libTDLiveness.a(Mob-Risk SDK liveness component library, is a static library type)
  • CWResource.bundle (Mob-Risk SDK liveness component Required resource package)

Import Header File

Please import the header file if you want to call SDK API.

#import <TDMobRisk/TDMobRisk.h>
import TDMobRisk

Initialization

Precautions

When the installation starts for the first time, the SDK initialization is performed after the user agrees with the privacy agreement.

Avoid SDK initialization collection without the user agreeing to the privacy agreement, causing compliance risk accidents.

Interface Definition

void (*initWithOptions)(NSDictionary *options);

initWithOptions method Required Configuration

Key Definition Description Scene Sample code
partner Partner code Partner, please contact TrustDecision to obtain All Scenes Objective C
[options setValue:@"[Your partner]" forKey:@"partner"];
Swift
options.updateValue("[Your partner]" as NSObject, forKey: "partner")
appKey App key Appkey, please offer your App bundleId for TrustDecision to obtain.
appkey creation requires the user to provide the application bundleId
All Scenes Objective C
[options setValue:@"[Your appKey]" forKey:@"appKey"];
Swift
options.updateValue("[Your appKey]" as NSObject, forKey: "appKey")
partnerKey partner key partnerKey, please contact TrustDecision to obtain All Scenes Objective C
[options setValue:@"[Your partnerKey]" forKey:@"partnerKey"];
Swift
options.updateValue("[Your partnerKey]" as NSObject, forKey: "partnerKey")
country Country code Country/region parameters, such as cn sg us fra idna Fill in the corresponding parameters according to country and region of business.
cn means China,
sg means Singapore,
us means North America,
fra means Europe,
idna means Indonesia
Objective C
[options setValue:@"[Your country code]" forKey:@"country"];
Swift
options.updateValue("[Your country code]" , forKey: "country")

Sample Code

- (void)initTrustDecisionSDK {
  // Get riskManager
  TDMobRiskManager_t *riskManager = [TDMobRiskManager sharedManager];
  // Initialization Configuration
  NSMutableDictionary *options = [NSMutableDictionary dictionary];

/*************************** Mandatory Parameter ***************************/
  //Partner code, Refer to `Required Configuration`
  [options setValue:@"[Your partner]" forKey:@"partner"];
  //App key, Refer to `Required Configuration`
  [options setValue:@"[Your appKey]" forKey:@"appKey"];
  //App name, Refer to `Required Configuration`
  [options setValue:@"[Your partnerKey]" forKey:@"partnerKey"];
  //Country code, Refer to `Required Configuration`
  [options setValue:@"[Your country code]" forKey:@"country"];

  /*************************** Optional Parameter ***************************/
#ifdef DEBUG
  // !!! If not set this parameter in DEBUG mode, the app will terminate
  [options setValue:@(YES) forKey:@"allowed"];
#endif
  // !!!The callback method has been removed, and now a getBlackBoxAsync method has been added to asynchronously obtain blackbox
  riskManager->initWithOptions(options);
}
func initTrustDecisionSDK() {
  let riskManager = TDMobRiskManager.sharedManager()
  var options = [String : NSObject]()
  /*************************** Mandatory Parameter ***************************/
  // Partner code, Refer to `Required Configuration`
  options.updateValue("[Your partner]" as NSObject, forKey: "partner")
  // App key, Refer to `Required Configuration`
  options.updateValue("[Your appKey]" as NSObject, forKey: "appKey")
  // App name, Refer to `Required Configuration`
  options.updateValue("[Your partnerKey]" as NSObject, forKey: "partnerKey")
  // Country code, Refer to `Required Configuration`
  options.updateValue("[Your country]" as NSObject, forKey: "country")

   /*************************** Optional Parameter ***************************/
#if DEBUG
  // !!! If not set this parameter in DEBUG mode, the app will terminate
  options.updateValue(true, forKey: "allowed")
#endif
  // !!!The callback method has been removed, and now a getBlackBoxAsync method has been added to asynchronously obtain blackbox
 riskManager?.pointee.initWithOptions(options)
}

Get Blackbox

Attention

  • Please getBlackBox after initWithOptions, otherwise SDK exceptions will be caused.
  • We suggest that developers do not cache the results returned by getBlackBox in the app. Please rely on this function to get blackBox.

Asynchronous method getBlackBoxAsync (recommend)

   /* Get blackBox asynchronously
    */
   void (*getBlackBoxAsync)(TDGetBlackBoxAsyncBlock block);

Usage Scenario Description

Advantages: Under normal circumstances, the network returns a non-degraded blackBox, which will reduce the amount of data uploaded by the subsequent query interface, and the data size is about 26 bytes;
Disadvantages: Not returned immediately, according to the network It usually takes about 300ms to return;
Applicable scenario: Need to get the latest and non-degraded blackBox scenario;

Sample Code

     TDMobRiskManager_t *riskManager = [TDMobRiskManager sharedManager];
     riskManager->getBlackBoxAsync(^(NSString* blackBox){
         NSLog(@"blackBox:%@", blackBox);
     });
    let riskManager = TDMobRiskManager.sharedManager()
    riskManager?.pointee.getBlackBoxAsync(){(blackBoxString : String!)->Void in
            print("blackBox:" + blackBoxString)                               
    }

Synchronous method getBlackBox

   /* Get blackBox synchronously
    * @return After the SDK is initialized, the blackBox obtained synchronously
    */
   NSString (*getBlackBox)(void);

Usage Scenario Description

Advantages: The blackBox will be returned immediately, not affected by the network status;
Disadvantages: After the device fingerprint SDK is integrated, if the non-degraded blackBox has not been obtained before, it will return to the degraded blackBox will increase the amount of data uploaded by the subsequent query interface, and the data size is about 5000 bytes;
Applicable scenarios: Scenes where blackBox needs to be obtained immediately;

Sample Code

   TDMobRiskManager_t *riskManager = [TDMobRiskManager sharedManager];
   NSString *blackBox = riskManager->getBlackBox();
  let riskManager = TDMobRiskManager.sharedManager()
  let blackBox = riskManager?.pointee.getBlackBox()

Popup Liveness Window

initWithOptions method Optional Parameter

Key Definition Description Scene Sample code
language language type Liveness detection prompt language
Default: en English Options:
en English
zh-Hans Simplified Chinese
zh-Hant Traditional Chinese
es Spanish
id Indonesian
ar Arabic
fil Filipino
ko Korean
pt Portuguese
ru Russian
th Thai
tr Turkish
vi Vietnamese
You can set the language type according to your needs Objective C
[options setValue:@"en" forKey:@"language"];
Swift
options.updateValue("en", forKey: "language")
playAudio Whether to play audio The default is NO, no audio will be played When turned on, the corresponding prompt audio will be played Objective C
[options setValue:@NO forKey:@"playAudio"];
Swift
options.updateValue(false, forKey: "playAudio")
livenessHttpTimeOut SDK network timeout configuration (unit: seconds) Default is 15s Customers can set the network timeout according to their needs Objective C
[options setValue:@8 forKey:@"livenessHttpTimeOut"];
Swift
options.updateValue(8, forKey: "livenessHttpTimeOut")
showReadyPage When starting the face, the detection preparation page will pop up Whether to display the preparation page, the default is YES, which means it will be displayed After closing, the preparation page will not be displayed, and the identification process will be shorter Objective C
[options setValue:@YES forKey:@"showReadyPage"];
Swift
options.updateValue(true, forKey: "showReadyPage")
faceMissingInterval Timeout when no face is detected (unit: milliseconds) No face timeout, unit ms, default is 1000ms Set the timeout period when no face is detected as needed Objective C
[options setValue:@(1000) forKey:@"faceMissingInterval"];
Swift
options.updateValue(1000, forKey: "faceMissingInterval")
prepareStageTimeout The starting time when preparing to detect the action (unit: seconds) Preparation phase timeout, in seconds, the default is 0S, that is, it will never time out Set the preparation phase timeout as needed Objective C
[options setValue:@(0) forKey:@"prepareStageTimeout"];
Swift
options.updateValue(0, forKey: "prepareStageTimeout")
actionStageTimeout In the action phase, the maximum verification time (unit: seconds) Action phase timeout, unit second, default is 8S Set the action phase timeout as needed Objective C
[options setValue:@(8) forKey:@"actionStageTimeout"];
Swift
options.updateValue(8, forKey: "actionStageTimeout")

showLiveness method

The showLiveness method is used to display the Liveness vc, and its interface is defined as follows

/**
 * Display Liveness window
 * @usage: manager->showLiveness(self,^(TDLivenessResultStruct resultStruct) {
 * });
 * @param targetVC The parent view where the popup is displayed, UIViewController type
 * @param block result callback block
*/
void (*showLiveness)(id targetVC,TDShowLivenessBlock block);

Callback parameter structure TDLivenessResultStruct

We use the TDLivenessResultStruct structure to store the result of the callback;

typedef enum {
    
    // The Liveness is verified successfully;
    TDLivenessResultTypeSuccess,
    // If the Liveness fails, you can get the error code errorCode and errorMsg, and check the cause according to the `Error code` in the document;
    TDLivenessResultTypeFailed,
    // The Liveness window pop-up is successful, waiting to be verified;
    TDLivenessResultTypeReady,
    
} TDLivenessResultType;

typedef struct _TDLivenessResultStruct{
    // return result type
    const TDLivenessResultType resultType;
    // the seqId of the Liveness returned
    char* const seqId;
    // After the return fails, the returned error code can be checked according to the document
    const NSInteger errorCode;
    // Return error message after failure
    char* const errorMsg;
    // liveness score when success
    double score;
    // best image string
    char* const bestImageString;
    
}TDLivenessResultStruct;

Example Code

- (void)showLiveness {
     [TDMobRiskManager sharedManager]->showLiveness(self,^(TDLivenessResultStruct resultStruct) {
         if(resultStruct.resultType == TDLivenessResultTypeSuccess){
             // If there is a best photo
             if(resultStruct.bestImageString.length > 0){
                 NSData* data = [[NSData alloc]initWithBase64EncodedString:resultStruct.bestImageString options:NSDataBase64DecodingIgnoreUnknownCharacters];
                 UIImage * image = [UIImage imageWithData:data];
                 UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
             }
            
             NSString*successMsg = [NSString stringWithUTF8String:resultStruct.errorMsg];
             NSLog(@"successMsg-::%@,score:%f",successMsg,resultStruct.score);
         }else{
             NSString*errorMsg = [NSString stringWithUTF8String:resultStruct.errorMsg];
             NSString*errorMsgInfo = [NSString stringWithFormat:@"Face detection failed, error code: %ld, error message: %@", resultStruct.errorCode,errorMsg];
             NSLog(@"errorMsgInfo-::%@",errorMsgInfo);
         }
     });
}

     func showLiveness() {
         let targetVC = self
         let riskManager = TDMobRiskManager.sharedManager()
         riskManager?.pointee.showLiveness(targetVC) { (resultStruct : TDLivenessResultStruct!)->Void in
             switch resultStruct.resultType {
             case TDLivenessResultTypeSuccess:
                 let bestImageString : String? = String(utf8String: resultStruct.bestImageString)
                 if(bestImageString != nil && bestImageString!.count > 0){
                     let data : Data? = Data(base64Encoded: bestImageString!)
                     if(data != nil){
                         let image : UIImage? = UIImage(data: data!)
                         if(image != nil){
                             UIImageWriteToSavedPhotosAlbum(image!, nil, nil, nil);
                         }
                     }
                 }
                 let successMsg = String(cString:resultStruct.errorMsg)
                 let seqId = String(cString:resultStruct.seqId)
                 print("Liveness successful!!!,seqId:\(seqId),successMsg:\(successMsg),score:\(resultStruct.score)")
             case TDLivenessResultTypeFailed:
                 let errorMsg = String(cString:resultStruct.errorMsg)
                 print("Liveness failed, errorCode:\(resultStruct.errorCode), errorMsg:\(errorMsg)")
             default:
                 break
             }
         }
     }

Get SDK Version

Sample Code

// Get SDK Version
TDMobRiskManager_t *riskManager = [TDMobRiskManager sharedManager];
NSString *sdkVersion = riskManager->getSDKVersion();
// Get SDK Version
let riskManager = TDMobRiskManager.sharedManager()
let sdkVersion = riskManager?.pointee.getSDKVersion()

Error Code

CodeMessageCharged
200success (live person)YES
20700No face detectedNO
20702Person change detectedNO
20703Detection timeoutNO
20705Screen lock or background exit during detectionNO
20710No camera permissionNO
20711User actively cancels detection on the preparation pageNO
20712User actively cancels detection on the detection pageNO
20749Inconsistent action, tilt head downNO
60001Network issue, failed to retrieve sessionNO
60002Network issue, failed to call anti-hackNO
12202Identified as a blink attackYES
12203Identified as a mouth movement attackYES
12204Identified as a partial face attackYES
12205Identified as a video replay attackYES
12206Identified as a black and white imageYES
12207Identified as a paper-based attackYES
12208Identified as a frame (including paper or phone frame)YES
12209Identified as a moire pattern attackYES
12210Identified as a face superiority attackYES
12211Identified as a paper-based attack (optical flow)YES
12212Identified as a mask attackYES
12213Identified as an ID card attackYES
12214Identified as a 3D mask attackYES
12215Identified as a synthetic image attackYES
12216Identified as a black-market software attackYES
12217Identified as a T-type mask attackYES
12218Identified as a blurry imageYES
12219Suspected deepfake image attackYES
12220Suspected high-resolution screen attackYES
12222Injection attackYES
12250Verification errorYES
11350Internal errorNO

FAQ

Q1: After integrated the TrustDecision SDK, the project can no longer be debugged in Xcode. How to solve it?

A1: Please refer to Initialization when initializing TrustDecision SDK, add the following parameters

[options setValue:@(YES) forKey:@"allowed"];
options.updateValue(true, forKey: "allowed")