---
updatedAt: 2026-09-21T10:33:29.000Z
agentTools:
  projectIndex: https://en-doc.trustdecision.com/llms.txt
---

# iOS-General

<br />

# 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

| Items                     | Description           |
| ------------------------- | --------------------- |
| Supported System Versions | iOS 9.0 and above     |
| Supported Architectures   | armv7, arm64, x86\_64 |

# Integrate

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

## Install

If installing offline, please refer to [Offline Install](https://en-doc.trustdecision.com/reference/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.2.1'` 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(**&#x53;wif&#x74;**&#x20;Package Manager)**

1. Open your Xcode project
2. Select `File` -> `Add Package Dependencies...`
3. Enter the repository URL:

```text
https://github.com/trustdecision/trustdevice-pro-ios.git
```

4. Set Dependency Rule to `Exact Version`
5. Enter version:

```text
5.3.2-1
```

6. Select your app target in Add to Target
7. 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:

```text
-ObjC
```

### Import Header File

```objective Objective C
#import <TDMobRisk/TDMobRisk.h>
```
```Text Swift
import TDMobRisk
```

## App Privacy Configuration

According to the latest [App Store Privacy Policy](https://developer.apple.com/news/?id=r1henawx) 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

```Text XML
<?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

```c
void (*initWithOptions)(NSDictionary *options);
```

## Get blackBox

### Cautions

* Call `getBlackBox` or `getBlackBoxAsync` after `initWithOptions`.
* Don't cache blackBox returned by getBlackBox in the app. Please rely on this function to get blackBox.

### Definition

```c
   /* Get blackBox asynchronously */
   void (*getBlackBoxAsync)(TDGetBlackBoxAsyncBlock block);
   /* Get blackBox synchronously */
   NSString (*getBlackBox)(void);
```

## Best Practices

1. Call initialization at entry of the application

```objective Objective C
- (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:@"country"];

/*************************** Optional  ***************************/
#ifdef DEBUG
  // Listen for error codes
  riskManager->setOnErrorCodeListener(^(int errorCode,const char* errorMsg){
        // If you want to use the variable 'errorMsg' in another thread, please first convert the string type using the following method to ensure that this value can be held normally by the other thread block
        NSString *errorMsgStr = [[NSString alloc] initWithCString:errorMsg ?: "" encoding:NSUTF8StringEncoding];
        NSLog(@":errorCode:%d,errorMsg:%@",errorCode,errorMsgStr);
   });

#endif
  riskManager->initWithOptions(options);
}
```
```Text Swift
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: "country")

   /*************************** Optional Parameter ***************************/
#if DEBUG
  // Listen for error codes
  riskManager?.pointee.setOnErrorCodeListener(){(errorCode : Int32!,errorMsg : UnsafePointer<CChar>!)->Void in
      // If you want to use the variable 'errorMsg' in another thread, please first convert the string type using the following method to ensure that this value can be held normally by the other thread block
			let errorMsgStr = String(validatingUTF8: errorMsg) ?? ""
			print("errorCode: \(errorCode), errorMsg: \(errorMsgStr)")
  }
#endif
  // !!!The callback method has been removed, and now a getBlackBoxAsync method has been added to asynchronously obtain blackBox
 riskManager?.pointee.initWithOptions(options)
}
```

1. Obtain blackBox in actual business scenarios

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

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

   2. If the blackBox has been successfully obtained through asynchronous method before, it can be directly obtained through synchronous method.

      ```objective Objective C
      // May be time-consuming, be cautious when calling in the main thread 
       TDMobRiskManager_t *riskManager = [TDMobRiskManager sharedManager];
       NSString *blackBox = riskManager->getBlackBox();
      ```
      ```Text Swift
      // May be time-consuming, be cautious when calling in the main thread
      let riskManager = TDMobRiskManager.sharedManager()
      let blackBox = riskManager?.pointee.getBlackBox()
      ```

## Status Check

1. getBlackBox() will return a 26-bit string while initialization successfully, like `rGPGX1678775227I9NCwcuVJCb`.
2. getBlackBox() will return a string of around 5000 bits while initialization Failed, please refer to [overview-definition](https://en-doc.trustdecision.com/reference/terminal-sdk-overview-2-0-en)

# Other

## Get SDK Version

```objective Objective C
TDMobRiskManager_t *riskManager = [TDMobRiskManager sharedManager];
NSString *sdkVersion = riskManager->getSDKVersion();
```
```Text Swift
let riskManager = TDMobRiskManager.sharedManager()
let sdkVersion = riskManager?.pointee.getSDKVersion()
```

## Error Listen

Please call setOnErrorCodeListener before the initWithOptions method to listen for error messages. It is recommended to use it only in debug mode.

```objective Objective C
TDMobRiskManager_t *riskManager = [TDMobRiskManager sharedManager];
riskManager->setOnErrorCodeListener(^(int errorCode,const char* errorMsg){
				// If you want to use the variable 'errorMsg' in another thread, please first convert the string type using the following method to ensure that this value can be held normally by the other thread block
        NSString *errorMsgStr = [[NSString alloc] initWithCString:errorMsg ?: "" encoding:NSUTF8StringEncoding];
        NSLog(@":errorCode:%d,errorMsg:%@",errorCode,errorMsgStr);
});
```
```Text Swift
let riskManager = TDMobRiskManager.sharedManager()
riskManager?.pointee.setOnErrorCodeListener(){(errorCode : Int32,errorMsg : UnsafePointer<CChar>?)->Void in
    // If you want to use the variable 'errorMsg' in another thread, please first convert the string type using the following method to ensure that this value can be held normally by the other thread block
		let errorMsgStr = String(validatingUTF8: errorMsg) ?? ""
      print("errorCode: \(errorCode), errorMsg: \(String(validatingUTF8: errorMsg))")
}
```

## All Configurations

<Table align={["left","left","left","left"]}>
  <thead>
    <tr>
      <th>
        Key
      </th>

      <th>
        Description
      </th>

      <th>
        Sample
      </th>

      <th>
        Remove Field
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        partner(required)
      </td>

      <td>
        Partner code, contact operator to obtain.
      </td>

      <td>
        **Objective C**<br />\[options setValue:@"your partner" forKey:@"partner"];<br />**Swift**<br /> options.updateValue("your partner" , forKey: "partner")
      </td>

      <td>

      </td>
    </tr>

    <tr>
      <td>
        appKey(required)
      </td>

      <td>
        Application identification, please refer to

        [how to get appKey](https://en-doc.trustdecision.com/reference/android-get-appkey)
      </td>

      <td>
        **Objective C**<br />\[options setValue:@"your appKey" forKey:@"appKey"];<br />**Swift**<br />options.updateValue("your appKey" , forKey: "appKey")
      </td>

      <td>

      </td>
    </tr>

    <tr>
      <td>
        country(required)
      </td>

      <td>
        Data-center：

        - cn for China
        - fra for Europe
        - sg for Singapore
        - idna for Indonesia
        - us for USA
        - hk for Hong Kong China
        - pk for Pakistan
        - th for Thailand
      </td>

      <td>
        **Objective C**<br />\[options setValue:@"cn" forKey:@"country"];<br />**Swift**<br />options.updateValue("cn" , forKey: "country")
      </td>

      <td>

      </td>
    </tr>

    <tr>
      <td>
        appName
      </td>

      <td>
        Application name, contact operator to obtain
      </td>

      <td>
        **Objective C**<br />\[options setValue:@"your appName" forKey:@"appName"];<br />**Swift**<br />options.updateValue("your appName", forKey: "appName")
      </td>

      <td>

      </td>
    </tr>

    <tr>
      <td>
        channel
      </td>

      <td>
        Channel, contact operator to obtain
      </td>

      <td>
        **Objective C**<br />\[options setValue:@"your channel" forKey:@"channel"];<br />**Swift**<br />options.updateValue("your channel", forKey: "channel")
      </td>

      <td>

      </td>
    </tr>

    <tr>
      <td>
        timeLimit
      </td>

      <td>
        Network timeout configuration, in seconds, default 15s
      </td>

      <td>
        **Objective C**<br />\[options setValue:@(5) forKey:@"timeLimit"];<br />**Swift**<br />options.updateValue(5, forKey: "timeLimit")
      </td>

      <td>

      </td>
    </tr>

    <tr>
      <td>
        location
      </td>

      <td>
        Whether collecting GPS location information, default allowed
      </td>

      <td>
        **Objective C**<br />\[options setValue:@(YES) forKey:@"location"];<br />**Swift**<br />options.updateValue(true, forKey: "location")
      </td>

      <td>
        latitude、longitude、gps_location
      </td>
    </tr>

    <tr>
      <td>
        IDFA
      </td>

      <td>
        Whether collecting IDFA information, default allowed
      </td>

      <td>
        **Objective C**<br />\[options setValue:@(YES) forKey:@"IDFA"];<br />**Swift**<br />options.updateValue(true, forKey: "IDFA")
      </td>

      <td>
        idfa
      </td>
    </tr>

    <tr>
      <td>
        IDFV
      </td>

      <td>
        Whether collecting IDFV information, default allowed
      </td>

      <td>
        **Objective C**<br />\[options setValue:@(YES) forKey:@"IDFV"];<br />**Swift**<br />options.updateValue(true, forKey: "IDFV")
      </td>

      <td>
        idfv
      </td>
    </tr>

    <tr>
      <td>
        wifiIp
      </td>

      <td>
        Whether collecting wifiIp information, default allowed
      </td>

      <td>
        **Objective C**<br />\[options setValue:@(NO) forKey:@"wifiIp"];<br />**Swift**<br />options.updateValue(false, forKey: "wifiIp")
      </td>

      <td>
        wifiIp
      </td>
    </tr>

    <tr>
      <td>
        cellIp
      </td>

      <td>
        Whether collecting cellIp information, default allowed
      </td>

      <td>
        **Objective C**<br />\[options setValue:@(NO) forKey:@"cellIp"];<br />**Swift**<br />options.updateValue(false, forKey: "cellIp")
      </td>

      <td>
        cellIp
      </td>
    </tr>

    <tr>
      <td>
        vpnIp
      </td>

      <td>
        Whether collecting vpnIp information, default allowed
      </td>

      <td>
        **Objective C**<br />\[options setValue:@(NO) forKey:@"vpnIp"];<br />**Swift**<br />options.updateValue(false, forKey: "vpnIp")
      </td>

      <td>
        vpnIp
      </td>
    </tr>

    <tr>
      <td>
        wifiIpv6
      </td>

      <td>
        Whether collecting wifiIpv6 information, default allowed
      </td>

      <td>
        **Objective C**<br />\[options setValue:@(NO) forKey:@"wifiIpv6"];<br />**Swift**<br />options.updateValue(false, forKey: "wifiIpv6")
      </td>

      <td>
        wifiIpv6
      </td>
    </tr>

    <tr>
      <td>
        deviceName
      </td>

      <td>
        Whether collecting device name information, default allowed
      </td>

      <td>
        **Objective C**<br />\[options setValue:@(NO) forKey:@"deviceName"];<br />**Swift**<br />options.updateValue(false, forKey: "deviceName")
      </td>

      <td>
        device_name
      </td>
    </tr>

    <tr>
      <td>
        ssid
      </td>

      <td>
        Whether collecting ssid information, default allowed
      </td>

      <td>
        **Objective C**<br />\[options setValue:@(NO) forKey:@"ssid"];<br />**Swift**<br />options.updateValue(false, forKey: "ssid")
      </td>

      <td>
        ssid、bssid
      </td>
    </tr>

    <tr>
      <td>
        collectLevel
      </td>

      <td>
        You can set M to control the maximum length of blackBox to 2000, default around 5000
      </td>

      <td>
        **Objective C**<br />\[options setValue:@"M" forKey:@"collectLevel"];<br />**Swift** <br />options.updateValue("M", forKey: "collectLevel")
      </td>

      <td>

      </td>
    </tr>

    <tr>
      <td>
        customMessage
      </td>

      <td>
        Custom messages, SDK supports transparent transmission and storage
      </td>

      <td>
        **Objective C**<br />\[options setValue:@"this is a customMessage" forKey:@"customMessage"];<br />**Swift**<br />options.updateValue("this is a customMessage", forKey: "customMessage")
      </td>

      <td>

      </td>
    </tr>
  </tbody>
</Table>

## Error Code

| code | how to handle                                                                                                                                                                                                                                     |
| ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 100  | Ensure initWithOptions is called before getBlackBox or getBlackBoxAsync                                                                                                                                                                           |
| 101  | Not affect usage. If you want to obtain a shorter blackBox, you can learn from the best practices mentioned above                                                                                                                                 |
| 102  | Not affect usage. If you want to obtain a shorter blackBox, try to use getBlackBox() after a successful callback of getBlackBoxAsync                                                                                                              |
| 200  | Required parameter exception, adjust according to the error message                                                                                                                                                                               |
| 201  | Please get in touch with our operator to update the validity period of the appKey                                                                                                                                                                 |
| 300  | Please first check if the timeLimit configuration has set a too short time. If it still cannot be resolved, please provide the blackBox, code, and error message to the technical for assistance                                                  |
| 301  | Please check the network status of the current device and App first                                                                                                                                                                               |
| 302  | Please first check if the appKey and partnerCode meet the document requirements. Then check if the appKey fits the bundleID. If it still cannot be resolved, please provide the blackBox, code, and error message to the technical for assistance |
| -1   | Please provide the blackBox, code, and error message to the technical for assistance                                                                                                                                                              |

# 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