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
Items | Description |
---|---|
Supported System Versions | iOS9.0+ |
Supporting architecture | armv7, arm64, x86_64 |
Integration Steps
There are 3 steps to integrate Liveness Detection SDK:
- Use the Retrive license API to get a license within the effective timeframe.
- Integrate the SDK for both Android and iOS platforms, initializing liveness detection process with the license generated in Step 1 and get the livenessId from the TDLivenessResultStruct structure.
- Use the Retrive result API with the "livenessId" generated in Step 2 to obtain a selfie if the liveness detection is successful, or receive detailed results in case of failure.
1. Retrive license API
Please follow the steps in https://en-doc.trustdecision.com/reference/liveness-api#retrive-license-api
2.SDK Integration methods
CocoaPods
- Added
pod 'TrustDecisionPro', '4.3.1.3'
in the corresponding target in the Podfile - In the Podfile corresponding to the target, if using the full version, Added
pod 'TrustDecisionLiveness', '2.4.1'
. If using the lite version, Addedpod 'TrustDecisionLiveness-Lite', '2.4.0'
. - Execute the
pod install --repo-update
command in the folder where the Podfile is located. (M1 series mac computers need to executearch -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") |
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"];
//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")
// 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
afterinitWithOptions
, 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 | Full Version | Lite Version | 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 |
✅ | ✅ | [options setValue:@"en" forKey:@"language"];
Swift options.updateValue("en", forKey: "language") |
playAudio | Whether to play audio ,the default is NO | ✅ | ✅ | Objective C [options setValue:@NO forKey:@"playAudio"]; Swift options.updateValue(false, forKey: "playAudio") |
livenessDetectionThreshold | Difficulty threshold for live detection,divided into three levels: high, medium, and low The default is medium | ✅ | Objective C [options setValue:@"medium" forKey:@"livenessDetectionThreshold"]; Swift options.updateValue("medium", forKey: "livenessDetectionThreshold") |
|
livenessHttpTimeOut | SDK network timeout configuration (unit: seconds),default is 15s | ✅ | 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,the default is YES, which means it will be displayed | ✅ | ✅ | Objective C [options setValue:@YES forKey:@"showReadyPage"]; Swift options.updateValue(true, forKey: "showReadyPage") |
faceMissingInterval | Timeout when no face is detected (unit: milliseconds),default is 1000ms | ✅ | 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),the default is 0S, that is, it will never time out | ✅ | Objective C [options setValue:@(0) forKey:@"prepareStageTimeout"]; Swift options.updateValue(0, forKey: "prepareStageTimeout") |
|
actionStageTimeout | In the action phase, the maximum verification time (unit: seconds), default is 8S | ✅ | 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 method
* @usage: manager->showLiveness(self,^(TDLivenessResultStruct resultStruct) {
* });
* @param targetVC VC, UIViewController type to display liveness window
* TrustDecisionLiveness version SDK will use [targetVC.navigationController pushViewController:livenessVC animated:YES]; method to display
* TrustDecisionLiveness-Lite version SDK will use [targetVC.view addSubview:[TDLiveness sharedManager].webView]; method to display
* @param block result callback
*/
void (*showLiveness)(id targetVC,TDShowLivenessBlock block);
/**
* Display liveness window method
* @usage: manager->showLivenessWithShowStyle(self,@"Input_your_license",TDLivenessShowStylePresent,^(TDLivenessResultStruct resultStruct) {
* });
* @param targetVC VC that displays the liveness window, UIViewController type, used with @param showStyle
* TrustDecisionLiveness version SDK will use
* if(showStyle == TDLivenessShowStylePush){[targetVC.navigationController pushViewController:livenessVC animated:YES];}
* else{[targetVC presentModalViewController:livenessVC animated:YES];} method to display
*
* TrustDecisionLiveness-Lite version SDK, @param showStyle is no longer effective, will use [targetVC.view addSubview:[TDLiveness sharedManager].webView]; method display
* @param license string type
* @param showStyle display style, TDLivenessShowStylePush or TDLivenessShowStylePresent
* @param block result callback
*/
void (*showLivenessWithShowStyle)(id targetVC,NSString* _Nullable license,TDLivenessShowStyle showStyle,TDShowLivenessBlock block);
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;
// liveness detection ID
char* const livenessId;
}TDLivenessResultStruct;
Example Code
- (void)showLiveness {
[TDMobRiskManager sharedManager]->showLivenessWithShowStyle(self,@"Input_your_license",TDLivenessShowStylePush,^(TDLivenessResultStruct resultStruct) {
// Success
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,livenessId:%s",successMsg,resultStruct.score,resultStruct.livenessId);
}
// Failed
else{
NSString*errorMsg = [NSString stringWithUTF8String:resultStruct.errorMsg];
NSString*errorMsgInfo = [NSString stringWithFormat:@"Face detection failed, error code: %ld, error message: %@,livenessId:%s", resultStruct.errorCode,errorMsg,resultStruct.livenessId];
NSLog(@"errorMsgInfo-::%@",errorMsgInfo);
}
});
}
func showLiveness() {
let targetVC = self
let riskManager = TDMobRiskManager.sharedManager()
riskManager?.pointee.showLivenessWithShowStyle(self,"Input_your_license",TDLivenessShowStyle(rawValue: TDLivenessShowStylePush.rawValue)){ (resultStruct : TDLivenessResultStruct!)->Void in
// Success
if(resultStruct.resultType == 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),livenessId:\(resultStruct.livenessId)")
}
// Failed
else{
let errorMsg = String(cString:resultStruct.errorMsg)
print("Liveness failed, errorCode:\(resultStruct.errorCode), errorMsg:\(errorMsg),livenessId:\(resultStruct.livenessId)")
}
}
}
Error Code
Code | Message |
---|---|
200 | success (live person) |
20700 | No face detected |
20702 | Person change detected |
20703 | Detection timeout |
20705 | Screen lock or background exit during detection |
20710 | No camera permission |
20711 | User actively cancels detection on the preparation page |
20712 | User actively cancels detection on the detection page |
20723 | Face too small |
20731 | Face not centered |
20732 | Face not facing the screen |
20749 | Inconsistent action, tilt head down |
60001 | Network issue, failed to retrieve session |
60002 | Network issue, failed to call anti-hack |
11350 | Internal error |
3. Retrive result API
Please follow the steps in https://en-doc.trustdecision.com/reference/liveness-api#retrive-result-api
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()
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")