# QI Tech — Risk Solutions › 设备扫描

Documentação da QI Tech em texto corrido, para colar em um LLM.
Fonte: https://docs.qitech.com.br
25 página(s).

Índice:
- DeviceScan 对象 (/zh-Hans/documentation/caas/device_scan/android/device_scan_object)
- 实现 (/zh-Hans/documentation/caas/device_scan/android/example)
- 混合解决方案 (/zh-Hans/documentation/caas/device_scan/android/hybrid_solutions)
- 信息收集 (/zh-Hans/documentation/caas/device_scan/android/information_gathering)
- 简介 (/zh-Hans/documentation/caas/device_scan/android/introduction)
- 原生集成 (/zh-Hans/documentation/caas/device_scan/android/native_java)
- 权限 (/zh-Hans/documentation/caas/device_scan/android/permissions)
- 认证 (/zh-Hans/documentation/caas/device_scan/api/authentication)
- QitechDeviceScan 对象 (/zh-Hans/documentation/caas/device_scan/flutter/device_scan_object)
- 实现 (/zh-Hans/documentation/caas/device_scan/flutter/example)
- 简介 (/zh-Hans/documentation/caas/device_scan/flutter/introduction)
- 权限 (/zh-Hans/documentation/caas/device_scan/flutter/permissions)
- QITechIosDeviceScan 对象 (/zh-Hans/documentation/caas/device_scan/ios/device_scan_object)
- 实现 (/zh-Hans/documentation/caas/device_scan/ios/example)
- 混合解决方案 (/zh-Hans/documentation/caas/device_scan/ios/hybrid_solutions)
- 信息收集 (/zh-Hans/documentation/caas/device_scan/ios/information_gathering)
- 简介 (/zh-Hans/documentation/caas/device_scan/ios/introduction)
- 原生集成 (/zh-Hans/documentation/caas/device_scan/ios/native_swift)
- 权限 (/zh-Hans/documentation/caas/device_scan/ios/permissions)
- Desktop Device Scan (/zh-Hans/documentation/caas/device_scan/web/desktop)
- DeviceScan 对象 (/zh-Hans/documentation/caas/device_scan/web/device_scan_object)
- 实现 (/zh-Hans/documentation/caas/device_scan/web/example)
- 导入库 (/zh-Hans/documentation/caas/device_scan/web/import)
- 收集返回值 (/zh-Hans/documentation/caas/device_scan/web/information_gathering)
- 简介 (/zh-Hans/documentation/caas/device_scan/web/introduction)

---

# DeviceScan 对象

URL: /zh-Hans/documentation/caas/device_scan/android/device_scan_object

要使用 DeviceScanSDK，需要实例化 DeviceScan 类。该实例接收 currentContext，并可以使用 token/session、环境和回调（notifier）进行配置。

:::danger 重要提示！
从版本 5.0.0 开始，认证系统已更新为使用临时 **token** 替代 **mobileToken**。
:::

## 版本 5.0.0+

| 参数 | 功能 | 必需 |
|------------|--------------|--------------|
|currentContext|应用程序上下文，用于访问所需数据。 |是。|
|token（通过 .setToken(this.token)）| 认证令牌，标识所收集数据来自您的应用程序。通过向 Device Scan API 发送请求获取令牌。 |是。|
|sessionId（通过 .setSessionId(this.sessionId)）|所收集数据所属会话的标识符。|是。|
|notifier（通过 .setNotifier(this.deviceScanNotifier)）|DeviceScanNotifier 实例。作为回调，返回发送状态（成功或失败）。 |否。|
|sandbox（通过 .setSandboxEnvironment()）|将库配置为向 `sandbox` 环境发送数据。如果未配置，请求将发送至 `production`。 |否。|

 **默认环境**：如果未调用 `setSandboxEnvironment()`，则发送至 `production`。

## 旧版本（4.x 及以下）

| 参数 | 功能 | 必需 |
|------------|--------------|--------------|
|currentContext|应用程序上下文，用于访问所需数据。|是。|
|mobileToken（通过 .setMobileToken(this.mobileToken)）|标识所收集数据来自您的应用程序的客户端密钥。如果您尚未收到 **mobile-token**，请联系支持团队：<a href='mailto:suporte.caas@qitech.com.br'>suporte.caas@qitech.com.br</a>。|是。|
|sessionId（通过 .setSessionId(this.sessionId)）|所收集数据所属会话的标识符。|是。|
|notifier（通过 .setNotifier(this.deviceScanNotifier)）|DeviceScanNotifier 实例。作为回调，返回发送状态（成功或失败）。|否。|
|sandbox（通过 .setSandboxEnvironment()）|将库配置为向 `sandbox` 环境发送数据。如果未配置，请求将发送至 `production`。 |否。|

## 快速摘要（迁移）
- 5.0.0+：使用临时 `token`（`setToken(this.token)`）
- < 5.0.0：使用 `mobileToken`（`setMobileToken(this.mobileToken)`）
- 两者均需：`currentContext` 和 `sessionId` 为必填项。`notifier` 和 `sandbox` 为可选项。

---

# 实现

URL: /zh-Hans/documentation/caas/device_scan/android/example

:::danger 重要提示！
从版本 5.0.0 开始，认证系统已更新为使用动态 **token** 替代 **mobileToken**。在配置 SDK 之前，您必须通过向我们的 Device Scan API 发送服务器间请求来生成临时 **token**。
:::

```java
package com.example.zaig_device_scan_sdk_test_app;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;

import com.qitech.android.devicescan.DeviceScan;
import com.qitech.android.devicescan.DeviceScanNotifier;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    private DeviceScan deviceScan;
    private DeviceScanNotifier deviceScanNotifier;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        deviceScanNotifier = new DeviceScanNotifier(this);
    }

    public void sendDeviceScan(View view) {
        try{
            deviceScan = new DeviceScan.Builder(this.getApplicationContext())
                .setToken(this.token)
                .setSessionId(this.sessionId)
                .setNotifier(this.deviceScanNotifier)
                .setSandboxEnvironment()
                .build();
        }catch (Exception ex) {
            Log.e("DeviceScan Error", "There was an error collecting DeviceScan data: " + ex.toString());
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults){
        try{
            deviceScan.collectData(this.documentNumber,
                    this.eventId,
                    this.eventType);
        }catch (Exception ex) {
            Log.e("DeviceScan Error", "There was an error collecting DeviceScan data: " + ex.toString());
        }
    }

    private class ScanNotifier implements DeviceScanNotifier {
        AppCompatActivity activity;
        public ScanNotifier (AppCompatActivity myActivity){
            // 此方法可自定义，可用于存储 Activity，用于操作 UI
            this.activity = myActivity;
        }

        public void onSuccess(){
            Log.i("DeviceScan", "DeviceScan successfully submitted");
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // 在设备扫描成功发送后，在此处添加所需的任何 UI 更改
                }
            });
        }

        public void onError(){
            Log.i("DeviceScan", "DeviceScan submission failed");
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // 在设备扫描成功发送后，在此处添加所需的任何 UI 更改
                }
            });
        }
    }
}

```

要使用 Android Device Scan SDK，需要执行以下步骤：

* 在应用程序 manifest 中添加权限；
* 将库导入应用程序项目；
* 在应用程序启动时，实例化库，并在构造函数中传入适当的参数，包括负责返回操作结果的 Notifier；
* 使用 Activity 的 `onRequestPermissionsResult` 函数获取权限请求批准或拒绝的结果通知；
* 向用户请求权限。互联网访问权限对于库的正常运行是必需的；
* 收到权限批准或拒绝结果后，通过 `collectData` 方法收集并发送数据。

---

# 混合解决方案

URL: /zh-Hans/documentation/caas/device_scan/android/hybrid_solutions

除了提供 Java 原生集成外，我们的 SDK 还与多种跨平台框架兼容。这通过集成针对每个框架的特定原生插件来实现。利用每个解决方案的原生系统，可以在 Android 环境中集成我们的原生 SDK。

一些最常用的混合技术包括 React Native（[Native Modules](https://reactnative.dev/docs/turbo-native-modules-introduction)）、Cordova（[Plugin Development Guide](https://cordova.apache.org/docs/en/latest/guide/hybrid/plugins/index.html)）、Ionic（[Native](https://ionicframework.com/docs/v3/native/)）、Unity（[Native Plug-in for Android](https://docs.unity3d.com/Manual/PluginsForAndroid.html)）、Xamarin（[Native Libraries](https://learn.microsoft.com/en-us/xamarin/android/platform/native-libraries)）、Appcelerator、Phonegap 和 Node。

为简化与我们原生解决方案的集成过程，我们为 React Native 和 Flutter 框架提供了插件。如有需要，我们可在私有仓库中提供文档和集成示例。对于其他技术，我们也有一些与原生代码桥接的实现示例。欢迎联系我们的支持团队 suporte.caas@qitech.com.br 获取访问权限。

---

# 信息收集

URL: /zh-Hans/documentation/caas/device_scan/android/information_gathering

要触发信息的收集和发送，需要（在获取用户权限后）调用 `collectData` 方法。该方法除了获取设备信息外，还旨在映射客户在应用程序中的使用流程。因此，该方法还接受 `eventId` 和 `eventType` 字段。该方法具有以下参数：

名称 | 类型 | 描述
---- | ---- | ---------
documentNumber | String | 用户的文件号码（如果可用）。（CPF/CNPJ，不含点、连字符和斜杠）
eventId | String | 正在报告的事件的标识符
eventType | String | 定义正在报告的事件类型的枚举值。建议注意，非常相似的事件应使用相同的枚举值进行报告，以便可以基于这些数据构建智能。

调用数据收集后，在 `DeviceScan` 类构造函数中传入的 `DeviceScanNotifier` 实例的两个方法之一将被调用：一切正常时调用 `onSuccess`，出现错误时调用 `onError`。

---

# 简介

URL: /zh-Hans/documentation/caas/device_scan/android/introduction

欢迎使用 QI Tech Android Device Scan 集成手册！您应使用我们的 SDK 收集应用程序中设备信息和用户行为数据，从而提高决策的准确性。

## 遇到问题？

我们不是躲在 API 后面的公司！请联系我们的[支持团队](mailto:suporte.caas@qitech.com.br)，我们将尽快回复。如果您需要快速回复，请随时致电我们！

### 我们热爱反馈

即使您已经解决了问题，或者问题非常简单（例如一个拼写错误或不当的组织方式），也请给我们发电子邮件。这样，我们可以让文档变得越来越实用，下一个人就不必经历同样的痛苦。

## 环境

我们为客户提供两个环境。通过 SDK 构造函数中传入的枚举值进行选择。目前，以下环境可用：

* 生产环境 - `production`
* 沙盒环境 - `sandbox`

:::danger 重要提示！
不得在 QI Tech 沙盒环境中使用真实的个人和/或法人数据。
:::

---

# 原生集成

URL: /zh-Hans/documentation/caas/device_scan/android/native_java

要导入我们的 SDK，需要对项目和应用程序的 build.gradle 文件进行更改。

## 添加到项目
在项目的 build.gradle 文件中（在 Android Studio 中，此文件显示为 "Project: \{项目名称\}"）添加我们 Maven 仓库的地址，如下例所示：

```java
buildscript {
    ...
}

allprojects {
    repositories {
        ...
        maven { url 'https://sdks.qitech.com.br/' }
    }
}
```

## 添加到应用程序
然后，在应用程序的 build.gradle 文件中（在 Android Studio 中，此文件显示为 **"Module: \{项目名称\}.app"**）添加您想要导入的库，包含以下依赖项：

```java
dependencies {
    ...
    implementation 'com.qitech.android:devicescan:v6.0.0'
}
```

:::warning
自 **2025 年 4 月**起，Google Play 新政策要求应用程序使用 **Android API Level 35** 才能在 Google Play Store 上发布或更新。因此，我们强烈建议您至少使用 **targetSdkVersion 35**。
:::

:::info
使用 **targetSdkVersion 35** 意味着使用 **compileSdkVersion 35**，这对 Android 生态系统工具有一些**最低要求**：
* compileSdkVersion 35 --> AGP 8.6.0
* AGP 8.6.0 --> Gradle 8.7
* AGP 8.6.0 --> Java 17 (JDK 17)
* AGP 8.6.0 --> Kotlin 2+
:::

## Manifest 文件

要使用 SDK，您必须在应用程序的 AndroidManifest 中添加以下配置：

```java
<meta-data
            android:name="com.google.android.gms.ads.AD_MANAGER_APP"
            android:value="true"/>
```

您还必须至少添加互联网权限，该权限用于将收集的数据发送到 QI Tech 服务器：

` `

权限列表应根据需要进行调整。

---

# 权限

URL: /zh-Hans/documentation/caas/device_scan/android/permissions

SDK 根据收集时可用的权限收集用户设备数据：您的应用请求的权限越多，用户授予的权限越多，可以收集的信息就越多。

:::info **注意**

INTERNET 权限是 SDK 能够将信息发送到 QI Tech 服务器的必要条件。
:::

## SDK 使用的权限

在当前版本的 SDK 中，以下权限在可用时可以使用：

| 权限 | 功能 | 必填 |
|------------|--------------|--------------|
|INTERNET|向 QI Tech 服务器发送信息。|是。|
|BLUETOOTH|捕获蓝牙硬件信息。|否。|
|BLUETOOTH_CONNECT|捕获蓝牙连接信息。|否。|
|READ_CONTACTS|读取联系人列表。|否。|
|ACCESS_COARSE_LOCATION|访问网络信息（基站、运营商等）及通过此方式获取位置（精度较低）。|否。|
|ACCESS_FINE_LOCATION|通过 GPS 访问位置（精度较高）。|否。|
|READ_PHONE_STATE|网络、SIM 卡、IMEI 及其他电话信息。|否。|
|QUERY_ALL_PACKAGES|设备上已安装应用的信息。Android 11 及以上版本的设备需要此权限。|否。|

:::info **重要**

我们的 SDK 不会主动请求上述权限。因此，为确保设备扫描更完整，建议在执行设备扫描调用前请求并获取这些权限。
:::

:::info **注意**

QUERY_ALL_PACKAGES 权限在应用发布时可能会与 Google Play 产生摩擦。为了解决这一问题，可以描述请求该权限的原因。
:::

---

# 认证

URL: /zh-Hans/documentation/caas/device_scan/api/authentication

:::danger 重要提示！
从 iOS 和 Android SDK 的 5.0.0 版本开始，认证系统已更新为使用临时令牌替代 mobileToken。
:::

我们使用 API Key 来允许访问我们的 API。通常，该密钥通过电子邮件发送。如果您尚未收到密钥，请发送邮件至 suporte.caas@qitech.com.br 。

## 临时认证令牌

在配置 SDK 之前，您必须通过向我们的 API 发送服务器间请求来生成临时令牌。

### 生成令牌

```bash
curl -X POST "https://d.viewpkg.com/device_scan/token" \
     -H "Authorization: EXAMPLE_API_KEY" \
     -H "Content-Type: application/json" \
     -d '{ "session_id": "unique_session_identifier" }'
```

**端点**

| 环境 | URL |
|----------|-----|
| 沙盒 | https://d.sandbox.viewpkg.com/device_scan/token |
| 生产 | https://d.viewpkg.com/device_scan/token |

**请求详情**

| 字段 | 类型 | 必需 | 描述|
|-------|------|------------|---------|
| session_id | string | 是 | 由您的系统生成的唯一会话标识符（例如，UUID）。 |

**Request Body**
```json
{
  "session_id": "unique_session_identifier" 
}
```

**Response Body**

成功响应将包含 `token` 字段。
```json
{
  "token": "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6..."
}
```

:::info 注意
请将 `EXAMPLE_API_KEY` 替换为从支持团队收到的 API Key。
:::

---

# QitechDeviceScan 对象

URL: /zh-Hans/documentation/caas/device_scan/flutter/device_scan_object

## 调用

要使用 Device Scan 插件，需要调用 'startDeviceScan' 方法，该方法具有以下参数：

| 参数 | 类型 | 功能 | 必需 |
|------------|--------------|--------------|--------------|
|mobileToken|String|标识所收集数据来自您的应用程序的客户端密钥。如果您尚未收到 mobile-token，请联系<a href='mailto:suporte.caas@qitech.com.br'>支持团队</a>。|是。|
|environment|CaaSEnvironment|用于将执行环境配置为 `sandbox` 或 `production` 的枚举值。 |是。|
|sessionId|String|标识所收集数据所属会话的密钥。|是。|
|eventType|String|定义正在报告的事件类型的枚举值——建议注意，非常相似的事件应使用相同的枚举值进行报告，以便可以基于这些数据构建智能。|是。|
|eventId|String|正在报告的事件的标识符|是。|
|documentNumber|String|用户的文件号码（如果可用）。（CPF/CNPJ，不含点、连字符和斜杠）|否。|

## 返回值

该方法返回一个字符串，表示信息收集期间的成功或失败：

### 成功

```javascript
DeviceScan data sent successfully
```

### 错误

```javascript
Device Scan fail. Check mobileToken, environment and permissions
```

---

# 实现

URL: /zh-Hans/documentation/caas/device_scan/flutter/example

```dart

import 'package:qitech_device_scan/qitech_device_scan.dart';

final _qitechDeviceScanPlugin = QitechDeviceScan();

final result = await _qitechDeviceScanPlugin.startDeviceScan(
    mobileToken: '<MOBILE_TOKEN_SENT_BY_QITECH>',
    environment: CaaSEnvironment.sandbox,
    sessionId: '<SESSION_ID>',
    eventType: '<EVENT_TYPE>',
    eventId: '<EVENT_ID>',
    documentNumber: '<USER_DOCUMENT_NUMBER>'
);

print('QiTech Device Scan result: ' + result);

```

## Flutter 设置

要使用 Device Scan 插件，需要执行以下步骤：

### 安装

首先，需要执行以下命令安装插件：

```bash
flutter pub add qitech_device_scan
```

该命令应安装最新版本，可在 `pubspec.yaml` 文件中验证：

```yaml
dependencies:
  qitech_device_scan: ^0.0.1
```

### 导入

现在，只需导入包即可开始使用：

```dart
import 'package:qitech_device_scan/qitech_device_scan.dart';
```

## Android 设置

在您的 `build.gradle` 文件中添加 Qi Tech Android 仓库引用：

```gradle
allprojects {
    repositories {
        maven { url 'https://sdks.qitech.com.br/' }
        ...
    }
}
```

通过在 `AndroidManifest.xml` 中添加以下代码来初始化 AdMob 服务：

```xml
<meta-data
    android:name="com.google.android.gms.ads.APPLICATION_ID"
    android:value="<ADMOB_APP_ID>"/>
```

如果您没有 `ADMOB_APP_ID`，请联系 suporte.caas@qitech.com.br 。

## iOS 设置

在您的 `Podfile` 文件中添加 Qi Tech Android 仓库引用：

```ruby
source 'https://cdn.cocoapods.org/'
source 'https://github.com/QITechSDKs/iOS.git'
```

直接通过 cocoapods 安装依赖项：

```bash
cd ios
pod install
```

或通过 flutter 安装：

```bash
flutter build ios
```

---

# 简介

URL: /zh-Hans/documentation/caas/device_scan/flutter/introduction

欢迎使用 QI Tech Flutter Device Scan 集成手册！您应使用我们的插件收集手机信息和应用程序中的用户行为数据，从而提高决策的准确性。

## 遇到问题？

我们不是躲在 API 后面的公司！请联系我们的[支持团队](mailto:suporte.caas@qitech.com.br)，我们将尽快回复。如果您需要快速回复，请随时致电我们！

### 我们热爱反馈

即使您已经解决了问题，或者问题非常简单（甚至是一个您已经理解的拼写错误或不当的组织方式），也请给我们发电子邮件，这样我们可以让文档变得越来越实用，下一个人就不必经历您所经历的痛苦！

## 环境

我们为客户提供两个环境。通过在插件调用参数中传入的枚举值进行选择。目前，以下环境可用：

* 生产环境 - `production`
* 沙盒环境 - `sandbox`

:::danger 重要提示！
不得在 QI Tech 沙盒环境中使用真实的个人和/或法人数据。
:::

---

# 权限

URL: /zh-Hans/documentation/caas/device_scan/flutter/permissions

插件根据收集时可用的权限来收集用户设备数据：您的应用程序请求的权限越多，用户授予的权限越多，能够从用户设备收集的信息就越多。

:::info **注意**

INTERNET 权限是 SDK 向 QI Tech 服务器发送信息的必要条件。
:::

## 插件使用的权限

:::info **重要**

我们的插件不会请求上述权限。因此，为确保更完整的设备扫描，我们建议在执行设备扫描调用之前收集这些权限。
:::

### Android

对于 Android 平台，如果以下权限可用，则使用：

| 权限 | 功能 | 必需 |
|------------|--------------|--------------|
|INTERNET|必需，用于向 QI Tech 服务器发送信息。| 是。 |
|BLUETOOTH|获取蓝牙硬件信息。| 否。 |
|BLUETOOTH_CONNECT|获取蓝牙连接信息。| 否。 |
|READ_CONTACTS|读取联系人列表。| 否。 |
|ACCESS_COARSE_LOCATION|访问网络信息（天线、运营商...）及通过此方式获取位置（精度较低）。| 否。 |
|ACCESS_FINE_LOCATION|通过 GPS 获取位置（精度较高）。| 否。 |
|READ_PHONE_STATE|网络、SIM 卡、IMEI 及其他电话功能信息。| 否。 |
|QUERY_ALL_PACKAGES|设备上已安装应用程序的信息。Android 11 及以上版本的设备需要此权限。| 否。 |

:::info **注意**

QUERY_ALL_PACKAGES 权限在应用程序发布时可能与 Google Play 产生摩擦。为解决此问题，可以描述请求该权限的原因。
:::

### iOS

对于 iOS 平台，如果以下权限可用，则使用：

* location - 获取设备地理位置数据

#### Info.plist 文件

为插件提供权限的第一步是在应用程序的 Info.plist 文件中配置权限，为每个所需权限使用以下代码行：

* location - 获取设备地理位置数据：

` NSLocationWhenInUseUsageDescription `
` 添加您希望在 iOS 请求地理位置访问权限时向用户显示的消息 `

:::info **注意**

为改善权限请求时的用户体验，您应按照前述方式自定义弹出请求中显示的消息。
:::

---

# QITechIosDeviceScan 对象

URL: /zh-Hans/documentation/caas/device_scan/ios/device_scan_object

要使用 QI Tech iOS DeviceScan，需要导入 QITechIosDeviceScan 框架，然后实例化 QITechIosDeviceScan 类，其构造函数具有以下参数：

:::danger 重要提示！
从版本 5.0.0 开始，认证系统已更新为使用临时 **token** 替代 **mobileToken**。
:::

## 版本 5.0.0+

名称 | 类型 | 描述
---- | ----- | ------
environment | String | 应用程序运行环境的枚举值 - `sandbox` 或 `production` - 如果发送了不同的值，将生成异常 **必填**
token | String | 认证令牌，标识所收集数据来自您的应用程序。通过向 Device Scan API 发送请求获取。**必填**
sessionId | String | 会话标识符（**必须与生成令牌时使用的相同**），将在事件评估时（例如交易、入驻）一同发送，用于关联设备扫描数据与待评估事件。**必填**

## 旧版本

名称 | 类型 | 描述
---- | ----- | ------
environment | String | 应用程序运行环境的枚举值 - `sandbox` 或 `production` - 如果发送了不同的值，将生成异常 **必填**
mobileToken | String | QI Tech 支持团队发送的客户端密钥，标识所收集数据来自您的应用程序。出于安全原因，如果此密钥不正确，QI Tech 服务器会接收但不处理该调用。**必填**
sessionId | String | 会话标识符，将在事件评估时（例如交易、入驻）一同发送，用于关联设备扫描数据与待评估事件。**必填**

---

# 实现

URL: /zh-Hans/documentation/caas/device_scan/ios/example

:::danger 重要提示！
从版本 5.0.0 开始，认证系统已更新为使用动态 **token** 替代 **mobileToken**。在配置 SDK 之前，您必须通过向我们的 Device Scan API 发送服务器间请求来生成临时 **token**。
:::

```swift
import UIKit
import QITechIosDeviceScan

class ViewController: UIViewController {

    var qitechDeviceScan : QITechIosDeviceScan?

    override func viewDidLoad() {
        super.viewDidLoad()
        self.setupDeviceScan()
    }

    func setupDeviceScan() -> Void
    {
        // The environment can be 'sandbox' ou 'production'
        let environment = "sandbox"

        // MobileToken is the key sent to you by QI Tech. Each environment requires a different MobileToken.
        let token = "TEMPORARY_TOKEN_FROM_DEVICE_SCAN_API"

        // You must send the same session id in the moment of using the device scan and event analysis. It must be a key that uniquely identifies each user session in the app
        let sessionId = "62715840-068a-4ded-a4e2-a1ec83f857d4"

        do{
            self.qitechDeviceScan = try QITechIosDeviceScan(environment: environment, token: token, sessionId: sessionId)
        }
        catch{
            print ("Error found when instantiating QITech's DeviceScan")
        }

        let permissions = ["location"]

        do{
            try self.qitechDeviceScan?.requestPermissions(permissions: permissions)
        }
        catch{
            print ("Error found when requesting QITech's DeviceScan's permissions")
        }
    }

    func onSuccess()
    {
        // Do something if QI Tech DeviceScan's collectData method succesfully collected device data
    }

    func onError()
    {
        // Do something if QI Tech DeviceScan's collectData method found any error when collecting device data
    }

    func collectQITechDeviceScanData()
    {
        // If you have your customer's document number (CPF or CNPJ without dots, hyphen or slash), you must sent it to QI Tech
        let documentNumber = "12345678900"

        // EventType must represent with type of interation the user had with your app on the moment that collectData method was called
        let eventType = "login"

        // EventId is your code that identifies the event sent to QI Tech
        let eventId = "7038632032"

        do{
            try self.qitechDeviceScan?.collectData(documentNumber: documentNumber, eventId: eventId, eventType: eventType, onSuccessHandler: self.onSuccess, onErrorHandler: self.onError)
        }
        catch{
            print("Error found when collecting QITech's DeviceScan data")
        }
    }
}
```

要使用 iOS Device Scan SDK，需要执行以下步骤：

在 Info.plist 文件中添加权限
将框架添加到应用程序项目
在应用程序启动时，实例化库，并传入适当的参数
如果您的应用程序尚未向用户请求权限，请通过之前实例化的对象的 `requestPermissions` 函数向用户请求权限
通过 `collectData` 方法收集并发送数据

---

# 混合解决方案

URL: /zh-Hans/documentation/caas/device_scan/ios/hybrid_solutions

除了提供 Swift 原生集成外，我们的 SDK 还与多种混合框架兼容。这通过集成针对每个框架的特定原生插件来实现。利用每个解决方案的原生系统，可以在 iOS 环境中集成我们的原生 SDK。

一些最常用的混合技术包括 React Native（[Native Modules](https://reactnative.dev/docs/turbo-native-modules-introduction)）、Cordova（[Plugin Development Guide](https://cordova.apache.org/docs/en/latest/guide/hybrid/plugins/index.html)）、Ionic（[Native](https://ionicframework.com/docs/v3/native/)）、Unity（[Native Plug-in for Android](https://docs.unity3d.com/Manual/PluginsForAndroid.html)）、Xamarin（[Native Libraries](https://learn.microsoft.com/en-us/xamarin/android/platform/native-libraries)）、Appcelerator、Phonegap 和 Node。

为简化与我们原生解决方案的集成过程，我们为 React Native 和 Flutter 框架提供了插件。如有需要，我们可在私有仓库中提供文档和集成示例。对于其他混合技术，我们也有一些与原生代码桥接的实现示例。欢迎联系我们的 支持团队 获取访问权限。

---

# 信息收集

URL: /zh-Hans/documentation/caas/device_scan/ios/information_gathering

要触发信息的收集和发送，需要调用 `collectData` 方法。该方法除了获取设备信息外，还旨在映射客户在应用程序中的使用流程。正因如此，该方法还接受 `eventId` 和 `eventType` 字段。另一个重要点是，该方法通过异步 HTTP 请求将信息发送到 QI Tech 服务器，因此请求成功或错误的通知是通过完成处理程序（Completion Handlers）完成的。该方法具有以下参数：

名称 | 类型 | 描述
---- | ---- | ---------
documentNumber | String | 用户的文件号码（如果可用）。（CPF/CNPJ，不含点、连字符和斜杠）
eventId | String | 正在报告的事件的标识符
eventType | String | 定义正在报告的事件类型的枚举值（例如：'login'）——注意，非常相似的事件应使用相同的枚举值进行报告，以便可以基于这些数据构建智能
onSuccessHandler | func() &#8209;> Void | 成功向 QI Tech 服务器发送数据时将调用的函数 **必填**
onErrorHandler | func() &#8209;> Void | 向 QI Tech 服务器发送数据时出现错误时将调用的函数 **必填**

---

# 简介

URL: /zh-Hans/documentation/caas/device_scan/ios/introduction

欢迎使用 QI Tech iOS Device Scan 集成手册！您应使用我们的 Framework 收集手机信息和应用程序中的用户行为数据，从而提高决策的准确性。

## 遇到问题？

我们不是躲在 API 后面的公司！请联系我们的[支持团队](mailto:suporte.caas@qitech.com.br)，我们将尽快回复。如果您需要快速回复，请随时致电我们！

### 我们热爱反馈

即使您已经解决了问题，或者问题非常简单（甚至是一个您已经理解的拼写错误或不当的组织方式），也请给我们发电子邮件，这样我们可以让文档变得越来越实用，下一个人就不必经历您所经历的痛苦！

## 环境

我们为客户提供两个环境。通过在 QITechIosDeviceScan 类构造函数中传入的枚举值进行选择。目前，以下环境可用：

* 生产环境 - `production`
* 沙盒环境 - `sandbox`

:::danger 重要提示！
不得在 QI Tech 沙盒环境中使用真实的个人和/或法人数据。
:::

---

# 原生集成

URL: /zh-Hans/documentation/caas/device_scan/ios/native_swift

## 远程安装

> 开始安装

```shell
  pod init
```

我们的 SDK 可以使用 CocoaPods 导入。

SDK | 当前版本
---- | -----
QITechIosDeviceScan | `pod 'QITechIosDeviceScan', '~> 6.0.0'`

:::info iOS Minimum Deployment Target
15.5
:::

要开始安装，请在项目根目录中执行左侧命令。

> 在 podfile 中添加 source

```ruby
   source 'https://github.com/QITechSDKs/iOS.git'
```

下一步是在 `podfile` 文件中添加 QI Tech source。

> 在 podfile 中添加 pod

```ruby
  pod 'QITechIosDeviceScan', '~> <version>'
```
最后，只需按照上述格式添加 `pod` 名称即可。

:::danger 注意：
架构变更（v5.0.0+）从版本 5.0.0 开始，SDK 以纯静态方式分发。在您的 Podfile 中，必须使用 :linkage => :static 配置。
:::

> Podfile 示例（版本 5.0.0 或更高）

```ruby
  source 'https://github.com/QITechSDKs/iOS.git'
  target 'ExampleApp' do
    use_frameworks! :linkage => :static
    pod 'QITechIosDeviceScan', '~> 6.0.0'
  end

  post_install do |installer|
    installer.pods_project.targets.each do |target|
      if ['DatadogCore', 'DatadogInternal', 'DatadogCrashReporting', 'DatadogLogs'].include?(target.name)
        target.build_configurations.each do |config|
          config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.5'
          config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
        end
      end
    end
  end
```

> Podfile 示例（旧版本）

```ruby
  source 'https://github.com/QITechSDKs/iOS.git'
  target 'ExampleApp' do
    use_frameworks!
    pod 'QITechIosDeviceScan', '~> 2.0.0'
  end

  post_install do |installer|
    installer.pods_project.targets.each do |target|
      if ['DatadogCore', 'DatadogInternal', 'DatadogCrashReporting', 'DatadogLogs'].include?(target.name)
        target.build_configurations.each do |config|
          config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.5'
          config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
        end
      end
    end
  end
```

:::info **注意**

需要为监控依赖项 'Datadog' 启用模块稳定性，以避免不同 Swift 版本可能存在的编译问题。因此，请将描述的块添加到 Podfile 的 post_install 中（如果已有 post_install 块，则将其包含在现有块中）。
:::

:::warning 注意
在 iOS 中集成依赖项时，可能需要对某些库使用静态链接，对其他库使用动态链接。此配置对于确保兼容性、避免构建错误和优化项目性能非常重要。
:::

### 依赖项混合链接（如有需要）
混合链接的需求是因为某些库有特定要求，有些需要静态链接以避免内部冲突和符号重复，而其他依赖项可能需要动态链接，因为它们是为模块化和项目间共享而设计的。

静态链接与动态链接的区别：
* 静态（static_framework）：库代码直接嵌入最终二进制文件，减少运行时加载时间，消除执行时的外部依赖。
* 动态（dynamic_framework）：库在运行时作为单独文件加载。这减小了最终二进制文件的大小，便于独立更新/修改。

> 在 Podfile 中配置混合链接

```ruby
...

use_frameworks! :linkage => :dynamic # 将默认链接模式配置为动态

...

static_frameworks = ['framework_1', 'framework_2', ...] # 包含所有需要静态链接的依赖项
pre_install do |installer|
  installer.pod_targets.each do |pod|
    if static_frameworks.include?(pod.name)
      def pod.static_framework?;
        true
      end
      def pod.build_type;
        Pod::BuildType.static_framework
      end
    end
  end
end
```

> 安装依赖项

```shell
  pod install
```

最后，执行 `pod install` 命令下载并安装依赖项。

---

# 权限

URL: /zh-Hans/documentation/caas/device_scan/ios/permissions

SDK 收集设备数据，根据 iOS 操作系统的运行方式，每个要收集的数据都需要特定权限。为了在嵌入 SDK 的应用中为用户提供自定义体验，我们实现了一种机制，使用开发者传入的参数向用户请求权限，遵循以下机制：

作为 `requestPermissions` 方法参数（以 String 格式）发送的权限将被请求给用户 - 除非之前已经请求过。
用户通过操作系统本身提供的对话框被询问框架认为必要的权限。
权限被批准或拒绝，当调用 `collectData` 方法时，它只会收集已获得权限的数据。

:::info **注意**

如果您的应用程序已经请求了必要的权限，则无需再次调用 `requestPermissions` 方法，SDK 将继承应用程序已请求的权限。
:::

## SDK 使用的权限

在当前版本的 SDK 中，以下权限在可用时可以使用：

* location - 捕获设备地理位置数据

## Info.plist 文件

为 SDK 提供权限的第一步是在应用的 Info.plist 文件中配置权限，对每个所需权限使用以下代码行：

* location - 捕获设备地理位置数据：

` NSLocationWhenInUseUsageDescription `
` 添加当 iOS 请求地理位置访问权限时您希望向用户显示的消息 `

:::info **注意**

为了在请求权限时提供更好的用户体验，您应该按照上述说明自定义弹出请求中显示的消息。
:::

---

# Desktop Device Scan

URL: /zh-Hans/documentation/caas/device_scan/web/desktop

这是 **Desktop Device Scan**，我们与 **Web Device Scan** 互补的 *white label* 模块。您可以使用我们的程序深度采集设备信息，并识别恶意软件的存在！

本软件是为满足 [Instrução Normativa BCB nº 491](https://www.bcb.gov.br/estabilidadefinanceira/exibenormativo?tipo=Instru%C3%A7%C3%A3o%20Normativa%20BCB&numero=491) 而开发的。它与 Web Device Scan 结合使用，能够为每台设备生成**唯一且可靠的标识**！

:::warning 注意
我们的应用程序是 *White Label* 的！您可以在安装程序中使用您自己的徽标，并自定义可执行文件名称和显示的消息，为您的用户提供更友好的体验。
:::

## 使用方法

在本步骤指南中，您将找到有关如何将程序与库结合使用的详细信息，以及 JavaScript 实现示例。通过这些，您将拥有将解决方案适配到您的用例所需的工具。

```html
<html>
<head>
    <script src="https://ds.viewpkg.com/device-scan-2-1-1.js"></script>
</head>

<script>
    var deviceScan = new vPkg.DeviceScan('web_token', 'session_id')
    deviceScan.setSandbox()
    deviceScan.setDesktop(true)
    deviceScan.info('event_type', 'event_id')
        .then((res) => console.log(res))
        .catch((error) => console.log(error))
</script>
</html>
```

使用 `deviceScan.setDesktop(true)` 标志时，Web SDK 将尝试识别已安装应用程序的存在。如果未安装或出现问题，您可能会收到以下错误之一：

| 错误                        | 描述                                                                                                                                                                                         |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Timeout in Secure App**   | 应用程序存在但未正确响应。请重新安装应用程序以解决问题。                                                                               |
| **Invalid desktop data**    | 应用程序已被修改或损坏。请重新安装应用程序以恢复完整性。                                                                                                                                                                                   |
| **Desktop App Not Present** | 应用程序未安装。请向用户提供 QI Tech 提供的下载链接。                                                                                                                                                                                   |
| **Unexpected App Error**    | 与应用程序通信时发生意外错误。如果重新安装后问题仍然存在，请联系支持团队：<a href='mailto:suporte.caas@qitech.com.br'>支持</a>。 |

## 支持的操作系统

**Desktop Device Scan** 适用于主流现代操作系统，在每个平台上提供原生兼容性和优化性能。

Windows 10/11 x64
macOS Intel (x86_64)
macOS Apple Silicon (M1/M2/M3)

---

# DeviceScan 对象

URL: /zh-Hans/documentation/caas/device_scan/web/device_scan_object

要使用设备扫描服务，需要实例化 DeviceScan 类，该类的构造函数具有以下参数：

| 参数 | 功能 | 是否必填 |
|------------|--------------|--------------|
|.setSandbox()|若在构造函数中使用此参数，库将配置为向 `sandbox` 环境发送数据。若不存在，请求将发送到 `production` 环境。|否。|
|.setGeoLocation(true)|若此参数设置为 `true`，库将请求收集 GPS 数据的权限。若不存在或设置为 `false`，则不会提取地理位置信息。|否。|

:::info **注意**
如果用户拒绝访问位置数据，库将正常运行，但不会收集这些信息。
:::

## deviceScan.info() 函数

要执行用户数据分析功能，需要向库发送以下参数，这些参数将标识您的公司以及信息所属的用户会话。此外，尽管 event_id 和 event_type 参数是可选的，但它们有助于我们识别用户在您页面上的导航模式，从而进一步防范欺诈。

以下是每个参数的详细说明：

名称 | 类型 | 描述
---- | ---- | ---------
web_token | String | 客户密钥，用于标识收集的数据来源于您的应用程序。如果尚未收到您的 web-token，请联系 支持团队 。**必填**
session_id | String | 标识收集数据所属会话的密钥。**必填**
event_id | String | 正在报告的事件的标识符
event_type | String | 定义正在报告的事件类型的枚举器 - 请注意，非常相似的事件应使用相同的枚举器报告，以便能够基于这些数据构建智能分析。

## 实现示例
一个简单的实现示例如下所示：

```html
   html>
    <head>
        <script src="https://ds.viewpkg.com/device-scan-2-1-1.js"></script>
    </head>

    <script>
        var deviceScan = new vPkg.DeviceScan('web_token', 'session_id')
        deviceScan.setSandbox()
        deviceScan.setGeoLocation(true)
        async function callDeviceScan(eventType, eventId) {
            await deviceScan.info(eventType, eventId)
            .then((res) => console.log(res))
            .catch((error) => console.log(error))
        }
    </script>

    <body>
        <input id="login" type="button" value="login" onclick="callDeviceScan('login', '1');" />
        <input id="buy" type="button" value="buy" onclick="callDeviceScan('buy', '2');" />
    </body> 
</html>
```

在上面的示例中，创建了一个辅助函数 **callDeviceScan**，以便将 Device Scan 的使用与按钮点击关联，数据收集函数可以被调用两次：

* 第一次是当用户按下登录按钮时，用户在此事件之前的特征和行为将与 web_token、session_id、event_type（"login"）和 event_id（"1"）标识符一起发送到 QI Tech 服务器。

* 第二次是当用户按下购买按钮时，使用相同的 web_token（指您的公司）和 session_id（指您用户的会话）标识符收集用户行为，但使用不同的 event_type（"buy"）和 event_id（"2"），表明在此步骤中执行了与之前不同的事件，从而映射用户在您网站上的完整旅程。

---

# 实现

URL: /zh-Hans/documentation/caas/device_scan/web/example

```html
   <html>
    <head>
        <script src="https://ds.viewpkg.com/device-scan-2-1-1.js"></script>
    </head>

    <script>
        var deviceScan = new vPkg.DeviceScan('web_token', 'session_id')
        deviceScan.setSandbox()
        deviceScan.setGeoLocation(true)
        deviceScan.info('event_type', 'event_id')
            .then((res) => console.log(res))
            .catch((error) => console.log(error))
    </script>
   </html>
```

库通过调用属于 **DeviceScan** 类的 **.info()** 函数来执行用户分析，该类包含在我们的 **vPkg** 库中，如上例所示。变量 'web_token'、'session_id'、'event_type'（**可选**）和 'event_id'（**可选**）应替换为**各自的真实值**。成功时，库将返回一个表示收集成功的字符串；失败时，将返回一个表示错误类型的字符串。

---

# 导入库

URL: /zh-Hans/documentation/caas/device_scan/web/import

要导入我们的库，请在您网站 HTML 的 **src** 标签中添加以下 URL：

```html
    <script src = "https://ds.viewpkg.com/device-scan-2-1-1.js"></script>
```

---

# 收集返回值

URL: /zh-Hans/documentation/caas/device_scan/web/information_gathering

Web Device Scan SDK 返回一个 _Promise_，成功情况下将返回一个**字符串**，表示流程已完成。
而在错误情况下，将返回一个包含错误描述的**字符串**。以下是如何映射每种情况并获取其结果的示例：

```html
    <script>
        var deviceScan = new vPkg.DeviceScan('web_token', 'session_id')
        deviceScan.setSandbox()
        deviceScan.setGeoLocation(true)
        deviceScan.info('event_type', 'event_id')
            .then((res) => console.log(res))
            .catch((error) => console.log(error))
    </script>
```

### 成功返回值

返回值 | 描述
--------- | ---------
Device Scan Successfully Sent | 设备扫描已成功完成，提取的信息也已成功发送。

### 错误返回值

错误 | 描述
--------- | ---------
Web Token Error | 使用的 Web Token 无效。如果您确认使用的是 QI Tech 提供的正确 Web Token，请立即联系我们的支持团队（suporte.caas@qitech.com.br）。
Invalid Request | 设备信息未正确收集。
Internal Server Error | 发生意外错误，请检查网络连接。

---

# 简介

URL: /zh-Hans/documentation/caas/device_scan/web/introduction

欢迎使用 QI Tech Web Device Scan 集成手册！您可以使用我们的库收集您网站上设备、浏览器和用户行为的信息，从而提高决策的准确性。

在本步骤指南中，您将找到库的详细信息以及 JavaScript 实现示例。通过这些，您拥有了将解决方案适配到您应用程序用例所需的工具。

## 遇到问题？

我们不是一个躲在 API 背后的公司！请联系我们的 支持团队 ，我们将尽快回复。如果您想要快速响应，也欢迎直接给我们打电话！

### 我们热爱反馈

即使您已经解决了问题，或者问题非常简单（哪怕只是一个拼写错误或您已经理解的组织问题），也请给我们发送电子邮件，这样我们可以让文档变得越来越实用，下一个人就不必经历您所经历的痛苦！

## 环境

我们为客户提供两个环境。通过在 SDK 构造函数中传递的枚举器进行选择，目前以下环境可用：

* 生产环境 - `production`
* 沙盒环境 - `sandbox`

:::danger 重要提示！
不得在 QI Tech 的沙盒环境中使用真实的个人和/或法人数据。
:::