集成要求
合规说明
请注意,在贵司的App中集成同盾提供的SDK产品时:
1.1 根据《网络安全法》《电信条例》《电信和互联网用户个人信息保护规定》等相关法律法规要求及监管实践中的标准,在贵司的最终用户首次启动App并在贵司开始采集信息之前,贵司应以交互界面或设计(如隐私政策弹窗等)向最终用户完整告知收集、使用、与第三方共享最终用户个人信息的目的、方式和范围,并征得最终用户的明示同意。
1.2 为向贵司提供业务安全和风控服务,同盾SDK将采集、处理、使用用户的手机终端唯一标志信息IDFA、Android ID、OAID、GAID、MAC 地址、无线IP地址、WIFI列表、无线路由器标识(BSSID、SSID)、设备类型、设备型号、系统类型、位置信息(粗略位置信息、精准位置信息)、登录 IP 地址等设备信息。为确保贵司使用相关服务的合规性,前述隐私政策应涵盖对同盾SDK提供服务并采集、处理、使用相关信息的授权,以下条款内容供贵司参考,具体表述可由贵司根据贵司隐私协议的整体框架和内容自行确定:
同盾SDK:为了业务安全和风控,我司使用了同盾 SDK,该 SDK 需要获取您的手机终端设备标识 IDFA、Android ID、OAID、GAID、MAC 地址、无线IP地址、WIFI列表、无线路由器标识(BSSID、SSID)、设备类型、设备型号、系统类型、位置信息(粗略位置信息、精准位置信息)、登录 IP 地址、应用程序列表、运行中进程信息、网络制式、设备软件版本号、传感器(光传感器、重力传感器、磁场传感器、加速度传感器、陀螺仪传感器、心率传感器)相关设备信息,用于设备欺诈风险识别。 |
同盾隐私协议:https://www.tongdun.cn/other/privacy/id=1
环境要求
说明 | |
---|---|
兼容版本 | iOS9.0+ |
支持架构 | armv7, arm64, x86_64 |
集成步骤
SDK接入示例代码(sample): https://github.com/trustdecision/mobrisk-ios-sample
安装配置
如果您使用离线文件的的安装方式,请参考:离线安装SDK指导
安装(CocoaPods)
- 在 Podfile 文件中对应 target 中新增 pod 'TrustDecisionPro', '4.3.0.2'
- 在 Podfile 所在文件夹中执行 pod install --repo-update 命令 (arm架构mac电脑需要执行 arch -x86_64 pod install --repo-update 命令)
引入头文件
在调用的位置引入头文件
#import <TDMobRisk/TDMobRisk.h>
import TDMobRisk
隐私文件配置
根据苹果公司公布的最新 App Store 隐私政策,自2024年春季开始,上架 App Store 的应用需要携带一份 App 的隐私清单文件。
从 2024 年 5 月 1 日开始,App Store Connect 不接受未在隐私清单文件中描述其使用所需原因 API 的应用程序。
适配措施
请根据您的实际情况选择解决方案进行处理:
- 工程目录中不存在 PrivacyInfo.xcprivacy 文件
- 在工程目录下通过 Xcode 新建 App Privacy 类型的文件,命名为 PrivacyInfo,同时勾选需要的 Targets
- 在工程目录中选中 PrivacyInfo.xcprivacy 文件并右击打开菜单,通过菜单中的 Open As -> Source Code 的方式打开文件
- 将下方 SDK 的 PrivacyInfo.xcprivacy 粘贴到工程目录的 PrivacyInfo.xcprivacy 文件中
- 工程目录中已存在 PrivacyInfo.xcprivacy 文件
- 在工程目录中选中 PrivacyInfo.xcprivacy 文件并右击打开菜单,通过菜单中的 Open As -> Source Code 的方式打开文件
- 在工程目录 PrivacyInfo.xcprivacy 文件中补充SDK 的 PrivacyInfo.xcprivacy 里有提及但工程目录 PrivacyInfo.xcprivacy 文件中仍缺失的内容
SDK 的 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>
初始化
注意事项
- 确保在用户同意隐私协议后,再进行SDK初始化。
方法定义
void (*initWithOptions)(NSDictionary *options);
获取blackBox
注意事项
- 请在 initWithOptions后调用getBlackBox
- 不要在App内对返回的blackBox进行缓存,获取blackBox请依赖getBlackBox方法
- 尽量在首次获取blackBox的异步回调触发之后,再同步获取blackBox
方法定义
// 异步回调获取
void (*getBlackBoxAsync)(TDGetBlackBoxAsyncBlock block);
// 同步获取
NSString (*getBlackBox)(void);
最佳实践
- 在应用程序入口处初始化并异步获取blackBox
- (void)initTrustDeviceSDK {
TDMobRiskManager_t *riskManager = [TDMobRiskManager sharedManager];
NSMutableDictionary *options = [NSMutableDictionary dictionary];
/*************************** 必传 ***************************/
// 合作方编码,参考下方全部配置说明
[options setValue:@"请输入您的合作方编码" forKey:@"partner"];
// 平台注册的应用标识,参考下方全部配置说明
[options setValue:@"请输入您的appKey" forKey:@"appKey"];
// 数据中心地区参数,参考下方全部配置说明`
[options setValue:@"请输入您所在的国家地区" forKey:@"country"];
#ifdef DEBUG
// !!! DEBUG模式下若不设置此参数,app运行会闪退
[options setValue:@(YES) forKey:@"allowed"];
// 监听错误码
riskManager->setOnErrorCodeListener(^(int errorCode,const char* errorMsg){
NSLog(@":errorCode:%d,errorMsg:%s",errorCode,errorMsg);
});
#endif
riskManager->initWithOptions(options);
riskManager->getBlackBoxAsync(^(NSString* blackBox){
NSLog(@"blackBox:%@",blackBox);
});
}
func initTrustDeviceSDK() {
let riskManager = TDMobRiskManager.sharedManager()
var options = Dictionary<String, Any>()
/*************************** 必传 ***************************/
// 合作方编码,参考下方全部配置说明
options.updateValue("请输入您的合作方编码", forKey: "partner")
// 平台注册的应用标识,参考下方全部配置说明
options.updateValue("请输入您的appKey", forKey: "appKey")
// 数据中心地区参数,参考下方全部配置说明
options.updateValue("请输入您所在的国家地区", forKey: "country")
#if DEBUG
// !!! DEBUG模式下若不设置此参数,app运行会闪退
options.updateValue(true, forKey: "allowed")
riskManager?.pointee.setOnErrorCodeListener(){(errorCode : Int32!,errorMsg : UnsafePointer<CChar>!)->Void in
print("errorCode: \(errorCode), errorMsg: \(String(validatingUTF8: errorMsg))")
};
#endif
riskManager?.pointee.initWithOptions(options)
riskManager?.pointee.getBlackBoxAsync(){(blackBoxString : String!)->Void in
print("blackBox:" + blackBoxString)
}
}
- 在实际业务节点同步获取blackBox
// 比如注册的时候
TDMobRiskManager_t *riskManager = [TDMobRiskManager sharedManager];
NSString *blackBox = riskManager->getBlackBox();
// 比如注册的时候
let riskManager = TDMobRiskManager.sharedManager()
let blackBox = riskManager?.pointee.getBlackBox()
状态检查
- SDK上报数据成功,getBlackBox()返回的结果长度为26位字符串。如: rIPGX1678775227I9NCwcuVJCb。
- 异常情况下,getBlackBox()返回的结果长度可能达到5000字符,详情可查看正常blackBox和降级blackBox的差异
其他说明
获取SDK版本号
TDMobRiskManager_t *riskManager = [TDMobRiskManager sharedManager];
NSString *sdkVersion = riskManager->getSDKVersion();
let riskManager = TDMobRiskManager.sharedManager()
let sdkVersion = riskManager?.pointee.getSDKVersion()
监听错误码
请在initWithOptions方法之前调用setOnErrorCodeListener来监听错误信息
TDMobRiskManager_t *riskManager = [TDMobRiskManager sharedManager];
riskManager->setOnErrorCodeListener(^(int errorCode,const char* errorMsg){
NSLog(@":errorCode:%d,errorMsg:%s",errorCode,errorMsg);
});
let riskManager = TDMobRiskManager.sharedManager()
riskManager?.pointee.setOnErrorCodeListener(){(errorCode : Int32,errorMsg : UnsafePointer<CChar>?)->Void in
print("errorCode:" + errorCode + "," + "errorMsg:" + errorMsg);
}
全部配置
配置Key | 说明 | 示例代码 | 移除字段 |
---|---|---|---|
partner(必须) | 合作方编码,请联系我司运营或者从客户平台获取 | Objective C [options setValue:@"请输入您的合作方编码" forKey:@"partner"]; Swift options.updateValue("请输入您的合作方编码" , forKey: "partner") | |
appKey(必须) | 应用标识,通过客户平台创建,参考如何申请appKey | Objective C [options setValue:@"请输入您的appKey" forKey:@"appKey"]; Swift options.updateValue("请输入您的appKey" , forKey: "appKey") | |
country(必须) | 数据中心地区: cn代表中国 us代表美国 sg代表新加坡 fra代表德国 idna代表印尼 | Objective C [options setValue:@"cn" forKey:@"country"]; Swift options.updateValue("cn" , forKey: "country") | |
allowed | 反调试功能,默认关闭,开发阶段请打开,发布时关闭 | Objective C [options setValue:@(YES) forKey:@"allowed"]; Swift options.updateValue(true, forKey: "allowed") | |
appName | 应用名称,请联系运营获取 | Objective C [options setValue:@"请输入您的appName" forKey:@"appName"]; Swift options.updateValue("请输入您的appName", forKey: "appName") | package_name |
channel | 渠道标识,请联系运营获取 | Objective C [options setValue:@"请输入您的channel" forKey:@"channel"]; Swift options.updateValue("请输入您的channel", forKey: "channel") | |
timeLimit | 网络请求回调的超时时间,单位秒,默认为15s | Objective C [options setValue:@(5) forKey:@"timeLimit"]; Swift options.updateValue(5, forKey: "timeLimit") | |
location | 是否采集地理位置信息,默认开启 | Objective C [options setValue:@(NO) forKey:@"location"]; Swift options.updateValue(false, forKey: "location") | latitude、longitude、gps_location |
IDFA | 是否采集广告标识符,默认开启 | Objective C [options setValue:@(NO) forKey:@"IDFA"]; Swift options.updateValue(false, forKey: "IDFA") | |
deviceName | 是否采集设备名称,默认开启 | Objective C [options setValue:@(NO) forKey:@"deviceName"]; Swift options.updateValue(false, forKey: "deviceName") | device_name |
ssid | 是否采集ssid信息,默认开启 | Objective C [options setValue:@(NO) forKey:@"ssid"]; Swift options.updateValue(false, forKey: "ssid") | ssid |
USE_DEMOTION | 降级时,是否优先使用降级数据,默认关闭 | Objective C [options setValue:@(YES) forKey:@"USE_DEMOTION"]; Swift options.updateValue(true, forKey: "USE_DEMOTION") | |
collectLevel | 配置降级blackBox裁剪长度,默认L大部分为5000字符左右,配置M后大部分在2000-5000字符区间,目前仅支持这两种配置。 | Objective C [options setValue:@"M" forKey:@"collectLevel"]; Swift options.updateValue("M", forKey: "collectLevel") | |
customMessage | 自定义消息,sdk支持透传和存储 | Objective C [options setValue:@"this is a customMessage" forKey:@"customMessage"]; Swift options.updateValue("this is a customMessage", forKey: "customMessage") |
错误码说明
错误码 | 处理方式 |
---|---|
100 | App启动后请保证initWithOptions在getBlackBox/getBlackBoxAsync之前调用。 |
101 | 不影响使用,如果希望获取更短的blackBox,可按照上文最佳实践方式使用 |
102 | 不影响使用,如果希望获取更短的blackBox,尽量在getBlackBoxAsync成功回调后使用getBlackBox获取blackBox |
200 | 必传参数异常,根据错误信息调整参数 |
201 | 请联系我司运营人员更新appKey有效期 |
202 | 检查初始化参数,在debug模式下,将 allowed 设置为 YES,进行调试 |
300 | 接口超时,检查是否通过timeLimit配置设置了过短的超时时间,默认15秒 |
301 | 网络异常,请先检查当前设备以及App网络状态 |
302 | 请先检查初始化参数appKey、partnerCode填写是否正确;然后检查appkey和包名、签名信息是否匹配。若还是无法解决,请提供降级的blackBox、code和错误信息给到技术人员协助处理 |
-1 | 请提供本次blackBox、code和错误信息给到技术人员协助处理 |