iOS

Requirement

Compliance

Please note that when integrating SDK products provided by 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 IDFA, AndroidID, OAID, MAC address, Wireless IP address, WIFI list, wireless router identification (BSSID, SSID),device type, device model, system type, geographical location(Rough location information, precise location information), login IP address 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 IDFA, AndroidID, OAID, GAID,MAC address, Wireless IP address, WIFI list, wireless router identification (BSSID, SSID),device type, device model, system type, geographical location(Rough location information, precise location information), login IP address, application list, running process, network type,device software version,sensor information(light sensor, gravity sensor, magnetic field sensor, acceleration sensor, gyroscope sensor) and other related device information, for fraud risk identification.

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

Environment

ItemsDescription
Supported System VersionsiOS 9.0 and above
Supported Architecturesarmv7, arm64, x86_64

Integrate

integrate sample : https://github.com/trustdecision/mobrisk-ios-sample

Install

If installing offline, please refer to Offline Install

Structure

  • TDMobRisk.xcframework(TrustDecision SDK, is a static library)
  • TDCorePlugin.xcframework (TrustDecision plugin, is an Embed dynamic library)
  • FMDeviceManagerFramework.xcframework (DeviceFingerprint SDK, is a static library)

Install(CocoaPods)

  • Add pod 'TrustDecisionPro', '5.3.1.2' to the target in the Podfile
  • Execute the pod install --repo-update command in the folder where the Podfile is located. (M series mac computers need to execute arch -x86_64 pod install --repo-update command)

Install(Swift Package Manager)

  1. Open your Xcode project
  2. Select File -> Add Package Dependencies...
  3. Enter the repository URL:
https://github.com/trustdecision/trustdevice-pro-ios.git
  1. Set Dependency Rule to Exact Version
  2. Enter version:
5.3.1-2
  1. Select your app target in Add to Target
  2. Click Add Package

Project Configuration

Add -ObjC to the host app target:

  1. Select TARGETS -> your app target
  2. Select Build Settings
  3. Search for Other Linker Flags
  4. Add:
-ObjC

Import Header File

#import <TDMobRisk/TDMobRisk.h>
import TDMobRisk

App Privacy Configuration

According to the latest App Store Privacy Policy announced by Apple, starting from the spring of 2024, apps listed on the App Store will need to carry an App privacy list document. Starting May 1, 2024, App Store Connect will not accept apps that do not describe their use of the required reason API in a privacy manifest file.

Adaptation Steps

Please choose a solution based on your actual situation.

  1. If the PrivacyInfo.xcprivacy file does not exist in the project directory
  • Create a new App Privacy type file through Xcode in the project directory, name it PrivacyInfo, and check the required Targets
  • Select the PrivacyInfo.xcprivacy file in the project directory and right-click to open the menu. Open the file through Open As -> Source Code in the menu
  • Paste the SDK's PrivacyInfo.xcprivacy below into the PrivacyInfo.xcprivacy file in the project directory
  1. If the PrivacyInfo.xcprivacy file already exists in the project directory
  • Select the PrivacyInfo.xcprivacy file in the project directory and right-click to open the menu. Open the file through Open As -> Source Code in the menu.
  • Added content in the PrivacyInfo.xcprivacy file in the project directory that is mentioned in SDK's PrivacyInfo.xcprivacy but is still missing in the project directory PrivacyInfo.xcprivacy file

SDK's PrivacyInfo.xcprivacy

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>NSPrivacyCollectedDataTypes</key>
	<array>
		<dict>
			<key>NSPrivacyCollectedDataType</key>
			<string>NSPrivacyCollectedDataTypeDeviceID</string>
			<key>NSPrivacyCollectedDataTypeLinked</key>
			<true/>
			<key>NSPrivacyCollectedDataTypeTracking</key>
			<false/>
			<key>NSPrivacyCollectedDataTypePurposes</key>
			<array>
				<string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
				<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
			</array>
		</dict>
	</array>
	<key>NSPrivacyAccessedAPITypes</key>
	<array>
		<dict>
			<key>NSPrivacyAccessedAPIType</key>
			<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
			<key>NSPrivacyAccessedAPITypeReasons</key>
			<array>
				<string>E174.1</string>
			</array>
		</dict>
		<dict>
			<key>NSPrivacyAccessedAPIType</key>
			<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
			<key>NSPrivacyAccessedAPITypeReasons</key>
			<array>
				<string>CA92.1</string>
			</array>
		</dict>
		<dict>
			<key>NSPrivacyAccessedAPIType</key>
			<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
			<key>NSPrivacyAccessedAPITypeReasons</key>
			<array>
				<string>35F9.1</string>
			</array>
		</dict>
	</array>
</dict>
</plist>

Initialization

Cautions

  • Ensure that it is initialized after the user agrees to the privacy agreement.

Definition

void (*initWithOptions)(NSDictionary *options);

Get blackBox

Cautions

  • Call getDeviceInfo after initWithOptions.
  • Don't cache blackBox returned by getDeviceInfo in the app. Please rely on this function to get blackBox.

Definition

/* Get blackBox asynchronously */
void (*getDeviceInfo)(TDDeviceInfoCallback callback);
/* Get blackBox synchronously */
TDDeviceResponse (*getDeviceInfoSync)(void);

Best Practices

  1. Call initialization at entry of the application
- (void)initTrustDecisionSDK {
  // Get riskManager
  TDMobRiskManager_t *riskManager = [TDMobRiskManager sharedManager];
  // Initialization Configuration
  NSMutableDictionary *options = [NSMutableDictionary dictionary];

/*************************** Required ***************************/
  // get from our customer platform
  [options setValue:@"[Your partner]" forKey:@"partner"];
  // get from our customer platform
  [options setValue:@"[Your appKey]" forKey:@"appKey"];
  //Data center, Refer to All configuration
  [options setValue:@"[Your data center]" forKey:@"dataCenter"];
  riskManager->initWithOptions(options);
}
func initTrustDecisionSDK() {
  let riskManager = TDMobRiskManager.sharedManager()
  var options = Dictionary<String, Any>()
  /*************************** Mandatory Parameter ***************************/
  // Partner code, Refer to `Required Configuration`
  options.updateValue("[Your partner]" , forKey: "partner")
  // App key, Refer to `Required Configuration`
  options.updateValue("[Your appKey]" , forKey: "appKey")
  // Data center, Refer to `Required Configuration`
  options.updateValue("[Your data center]" , forKey: "dataCenter")
  riskManager?.pointee.initWithOptions(options)
}
  1. Obtain blackBox in actual business scenarios

    1. Recommend using asynchronous methods to obtain without affecting the calling thread.

      TDMobRiskManager_t *riskManager = [TDMobRiskManager sharedManager];
      riskManager->getDeviceInfo(^(TDDeviceResponse response) {
      // ❗️Attention❗️Must perform NSString type conversion first. Otherwise other threads are not allowed to directly use the response object or its results.
          NSString *blackBox = [NSString stringWithUTF8String:response.blackBox ?: ""];
       		int code = response.apiStatus.code;
        	NSString *message = [NSString stringWithUTF8String:response.apiStatus.message ?: ""];
      		NSLog(@"code:%d,message:%@\nblackBox:%@",code,message,blackBox);
      });
      
      let riskManager = TDMobRiskManager.sharedManager()
      riskManager?.pointee.getDeviceInfo({ response in
          // ❗️Attention❗️Must perform String type conversion first. Otherwise other threads are not allowed to directly use the response object or its results.
          let blackBox = response.blackBox.flatMap { String(cString: $0) } ?? ""
          let code = response.apiStatus.code
          let message = response.apiStatus.message.flatMap { String(cString: $0) } ?? ""
          print("code:\(code),message:\(message)\nblackBox:\(blackBox)")
      })
    2. If the blackBox has been successfully obtained through asynchronous method before, it can be directly obtained through synchronous method.

      // May be time-consuming, be cautious when calling in the main thread 
      TDMobRiskManager_t *riskManager = [TDMobRiskManager sharedManager];
      TDDeviceResponse response = riskManager->getDeviceInfoSync();
      // ❗️Attention❗️Must perform NSString type conversion first. Other threads are not allowed to directly use the response object or its results.
      NSString *blackBox = [NSString stringWithUTF8String:response.blackBox ?: ""];
      // May be time-consuming, be cautious when calling in the main thread
      let riskManager = TDMobRiskManager.sharedManager()
      let response = riskManager?.pointee.getDeviceInfoSync()
      // ❗️Attention❗️Must perform String type conversion first. Other threads are not allowed to directly use the response object or its results.
      let blackBox = response?.blackBox.flatMap { String(cString: $0) } ?? ""

Status Check

  1. getDeviceInfo() will return a 26-bit string while initialization successfully, like rGPGX1678775227I9NCwcuVJCb.
  2. getDeviceInfo() will return a string of around 5000 bits while initialization Failed, please refer to overview-definition

Other

Get SDK Version

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

All Configurations

KeyDescriptionSampleRemove Field
partner(required)Partner code, contact operator to obtain.Objective C
[options setValue:@"your partner" forKey:@"partner"];
Swift
options.updateValue("your partner" , forKey: "partner")
appKey(required)

Application identification, please refer to

how to get appKey

Objective C
[options setValue:@"your appKey" forKey:@"appKey"];
Swift
options.updateValue("your appKey" , forKey: "appKey")
dataCenter(required)Data-center:
  • cn for China
  • fra for Europe
  • sg for Singapore
  • idna for Indonesia
  • us for the USA
❗️Note: country is deprecated but still works for now. We recommend using dataCenter instead.
Objective C
[options setValue:@"cn" forKey:@"dataCenter"];
Swift
options.updateValue("cn" , forKey: "dataCenter")
appNameApplication name, contact operator to obtainObjective C
[options setValue:@"your appName" forKey:@"appName"];
Swift
options.updateValue("your appName", forKey: "appName")
channelChannel, contact operator to obtainObjective C
[options setValue:@"your channel" forKey:@"channel"];
Swift
options.updateValue("your channel", forKey: "channel")
timeLimitNetwork timeout configuration, in seconds, default 15sObjective C
[options setValue:@(5) forKey:@"timeLimit"];
Swift
options.updateValue(5, forKey: "timeLimit")
locationWhether collecting GPS location information, default allowedObjective C
[options setValue:@(YES) forKey:@"location"];
Swift
options.updateValue(true, forKey: "location")
latitude、longitude、gps_location
IDFAWhether collecting IDFA information, default allowedObjective C
[options setValue:@(YES) forKey:@"IDFA"];
Swift
options.updateValue(true, forKey: "IDFA")
idfa
IDFVWhether collecting IDFV information, default allowedObjective C
[options setValue:@(YES) forKey:@"IDFV"];
Swift
options.updateValue(true, forKey: "IDFV")
idfv
wifiIpWhether collecting wifiIp information, default allowedObjective C
[options setValue:@(NO) forKey:@"wifiIp"];
Swift
options.updateValue(false, forKey: "wifiIp")
wifiIp
cellIpWhether collecting cellIp information, default allowedObjective C
[options setValue:@(NO) forKey:@"cellIp"];
Swift
options.updateValue(false, forKey: "cellIp")
cellIp
vpnIpWhether collecting vpnIp information, default allowedObjective C
[options setValue:@(NO) forKey:@"vpnIp"];
Swift
options.updateValue(false, forKey: "vpnIp")
vpnIp
wifiIpv6Whether collecting wifiIpv6 information, default allowedObjective C
[options setValue:@(NO) forKey:@"wifiIpv6"];
Swift
options.updateValue(false, forKey: "wifiIpv6")
wifiIpv6
deviceNameWhether collecting device name information, default allowedObjective C
[options setValue:@(NO) forKey:@"deviceName"];
Swift
options.updateValue(false, forKey: "deviceName")
device_name
ssidWhether collecting ssid information, default allowedObjective C
[options setValue:@(NO) forKey:@"ssid"];
Swift
options.updateValue(false, forKey: "ssid")
ssid、bssid
collectLevelYou can set M to control the maximum length of blackBox to 2000, default around 5000Objective C
[options setValue:@"M" forKey:@"collectLevel"];
Swift
options.updateValue("M", forKey: "collectLevel")
customMessageCustom messages, SDK supports transparent transmission and storageObjective C
[options setValue:@"this is a customMessage" forKey:@"customMessage"];
Swift
options.updateValue("this is a customMessage", forKey: "customMessage")

Response Result

The getDeviceInfo() function returns the response data in callback.

KeyDescription
blackBoxCall log query identifier
fpVersionSDK Version

Status Code

Call the TDDeviceManager getDeviceInfo() method. The parameter of type TDDeviceAPIStatus in the callback stores the status information of the SDK. Its definition is as follows:

typedef struct TDDeviceAPIStatus_Void {
    /// code
    int code;
    /// message
    NSString *message;
    
} TDDeviceAPIStatus;

The corresponding values of code and message are as follows:

CodeMessageRemarks
0Success.Success
1000Access error.Access exception occurs, possible causes: abnormal input parameters or network environment anomalies
1001SDK error.SDK exception occurs, possible reasons:Initialization function not called
1002Network error.Network Error
1003API error.The server returns an error
1004Traffic limit.Gateway current limiting return
1005Traffic shutdown.Traffic shutdown
1100Unknown error.Unknown error

QA

Q1: How to solve the problem of warning "The archive did not include a dSYM for the TDCorePlugin.framework with the UUIDs" after using Archive to package and Distribute on Testflight or AppStore?

A1: It will not have any impact on the current App distribute, please ignore this warning