# QI Tech — Risk Solutions › Device Scan

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

Índice:
- The DeviceScan Object (/en/documentation/caas/device_scan/android/device_scan_object)
- Implementation (/en/documentation/caas/device_scan/android/example)
- Hybrid Solutions (/en/documentation/caas/device_scan/android/hybrid_solutions)
- Information Gathering (/en/documentation/caas/device_scan/android/information_gathering)
- Introduction (/en/documentation/caas/device_scan/android/introduction)
- Native Integration (/en/documentation/caas/device_scan/android/native_java)
- Permissions (/en/documentation/caas/device_scan/android/permissions)
- Authentication (/en/documentation/caas/device_scan/api/authentication)
- The QitechDeviceScan object (/en/documentation/caas/device_scan/flutter/device_scan_object)
- Implementation (/en/documentation/caas/device_scan/flutter/example)
- Introduction (/en/documentation/caas/device_scan/flutter/introduction)
- Permissions (/en/documentation/caas/device_scan/flutter/permissions)
- The QITechIosDeviceScan object (/en/documentation/caas/device_scan/ios/device_scan_object)
- Implementation (/en/documentation/caas/device_scan/ios/example)
- Hybrid solutions (/en/documentation/caas/device_scan/ios/hybrid_solutions)
- Information gathering (/en/documentation/caas/device_scan/ios/information_gathering)
- Introduction (/en/documentation/caas/device_scan/ios/introduction)
- Native integration (/en/documentation/caas/device_scan/ios/native_swift)
- Permissions (/en/documentation/caas/device_scan/ios/permissions)
- Desktop Device Scan (/en/documentation/caas/device_scan/web/desktop)
- The DeviceScan object (/en/documentation/caas/device_scan/web/device_scan_object)
- Implementation (/en/documentation/caas/device_scan/web/example)
- Importing the library (/en/documentation/caas/device_scan/web/import)
- Collecting the returns (/en/documentation/caas/device_scan/web/information_gathering)
- Introduction (/en/documentation/caas/device_scan/web/introduction)

---

# The DeviceScan Object

URL: /en/documentation/caas/device_scan/android/device_scan_object

To use DeviceScanSDK, you must instantiate the DeviceScan class. This instance receives currentContext and can be configured with token/session, environment, and an optional callback (notifier).

:::danger Important Reminder!
Starting from version 5.0.0, the authentication system was updated to use a temporary **token** instead of **mobileToken**.
:::

## Versão 5.0.0+

| Parameter | Purpose | Required |
|------------|--------------|--------------|
|currentContext|The application context, used to access required data. |Yes.|
|token (via .setToken(this.token))| Temporary authentication token that identifies that the collected data comes from your application. The token is obtained by making a request to the Device Scan API. |Yes.|
|sessionId (via .setSessionId(this.sessionId))|Session identifier from which the collected data originates. |Yes.|
|notifier (via .setNotifier(this.deviceScanNotifier))|An instance of `DeviceScanNotifier`. Works as a callback, returning the delivery status (success or failure). |No.|
|sandbox (via .setSandboxEnvironment())|Configures the library to send data to the `sandbox` environment. If not set, requests are sent to `production`. |No.|

 **Default environment**: if `setSandboxEnvironment()` is not called, requests are sent to `production`. 

## Earlier Versions (up to 4.x)

| Parameter | Purpose | Required |
|------------|--------------|--------------|
|currentContext|The application context, used to access required data. |Yes.|
|mobileToken (via .setMobileToken(this.mobileToken))|Customer key that identifies that the collected data comes from your application. If you have not yet received your **mobile-token**, contact support at: <a href='mailto:suporte.caas@qitech.com.br'>suporte.caas@qitech.com.br</a>.|Yes.|
|sessionId (via .setSessionId(this.sessionId))|Session identifier from which the collected data originates. |Yes.|
|notifier (via .setNotifier(this.deviceScanNotifier))|An instance of `DeviceScanNotifier`. Works as a callback, returning the delivery status (success or failure).|No.|
|sandbox (via .setSandboxEnvironment())|Configures the library to send data to the `sandbox` environment. If not set, requests are sent to `production. |No.|

## Quick Summary (Migration)
- 5.0.0+: use a temporary `token` (`setToken(this.token)`)
- < 5.0.0: use `mobileToken` (`setMobileToken(this.mobileToken)`)
- In both: `currentContext` and `sessionId` are required. `notifier` and `sandbox` are optional.

---

# Implementation

URL: /en/documentation/caas/device_scan/android/example

:::danger Aviso Importante!
Starting from version 5.0.0, the authentication system has been updated to use a dynamic **token** instead of **mobileToken**. Before configuring the SDK, you must generate a temporary **token** through a server-to-server request to our Device Scan API.
:::

```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){
            // This method is customizable and can be used to store the Activity, which is used to operate the UI
            this.activity = myActivity;
        }

        public void onSuccess(){
            Log.i("DeviceScan", "DeviceScan successfully submitted");
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // Add here any UI changes that are required after the device scan is sent successfully
                }
            });
        }

        public void onError(){
            Log.i("DeviceScan", "DeviceScan submission failed");
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // Add here any UI changes that are required after the device scan is sent successfully
                }
            });
        }
    }
}

```

To use the Android device scan SDK, the following steps are required: 

* Add the required permissions to the application's manifest;
* Import the library into the application project;
* When starting the application, instantiate the library, passing the appropriate parameters in its constructor, including the Notifier, responsible for providing the operation callback with the result;
* Use the Activity’s `onRequestPermissionsResult` function to be notified of whether the required permissions were approved or not;
* Request permissions from the user. Internet access permission is mandatory for the library to work;
* Once you are notified of whether permissions were approved or not, collect and send the data using the `collectData` method.

---

# Hybrid Solutions

URL: /en/documentation/caas/device_scan/android/hybrid_solutions

In addition to offering native integration in Java, our SDKs are also compatible with several cross-platform frameworks. This is made possible through the integration of native plugins tailored to each framework. By leveraging each solution’s native layer, it is possible to incorporate our native Android SDK.

Some of the most widely used cross-platform technologies include 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 para Android](https://docs.unity3d.com/Manual/PluginsForAndroid.html)), Xamarin ([Native Libraries](https://learn.microsoft.com/en-us/xamarin/android/platform/native-libraries)), Appcelerator, Phonegap and Node.

To simplify the integration process with our native solutions, we provide plugins for the React Native and Flutter frameworks. If you’re interested, we can provide the documentation and an integration example in our private repositories. For the other cross-platform technologies, we also have a few examples showing how to implement this bridge with the native code. Feel free to contact our support suporte.caas@qitech.com.br to request access.

---

# Information Gathering

URL: /en/documentation/caas/device_scan/android/information_gathering

To trigger data collection and submission, you must (after obtaining the user’s permissions) call the `collectData`. method. In addition to capturing device information, this method is intended to map the customer journey within the application. For this reason, it also accepts the `eventId` and `eventType` fields. The method takes the following parameters:

name | type | definition
---- | ---- | ---------
documentNumber | String | The user’s document number, if available (CPF/CNPJ without dots, dashes, or slashes)
eventId | String | An identifier for the event being reported
eventType | String | An enumerated value that defines the type of event being reported. Take care to ensure that very similar events are reported with the same enum value, so that intelligence can be built on top of this data.

After the data collection call, one of the two methods on the `DeviceScanNotifier` instance passed into the `DeviceScan` constructor will be called: `onSuccess` if all goes as expected, or `onError` if an error occurs.

---

# Introduction

URL: /en/documentation/caas/device_scan/android/introduction

Welcome to the QI Tech Android Device Scan integration manual! You should use our SDK to collect device information and user behavior data in your application and, in doing so, improve the accuracy of decision-making.

## Having Issues?

We’re not a company that hides behind an API. Get in touch with our [support](mailto:suporte.caas@qitech.com.br) and we’ll respond as quickly as possible. Feel free to call us if you need a faster response!

### We love Feedback

Even if you’ve already solved your issue, or if it’s very simple (even a typo or a poorly organized section), please send us an email. This helps us make the documentation more and more practical, so the next person won’t have to go through the same pain.

## Environments

We provide two environments for our customers. The selection is made through an enum passed into the SDK constructor. Currently, the following environments are available:

* Produção - `production`
* Sandbox - `sandbox`

:::danger Important Note!
Real personal and/or business data must not be used in QI Tech’s Sandbox environments.
:::

---

# Native Integration

URL: /en/documentation/caas/device_scan/android/native_java

To import our SDKs, you must make changes to the project and app build.gradle files.

## Adding it to the Project

Add the URL of our Maven repository to the project’s build.gradle (in Android Studio, this file appears as “Project: \{project_name\}”), as shown below:

```java
buildscript {
    ...
}

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

## Adding it to the App
Next, add the library you want to import to the app’s build.gradle (in Android Studio, this file appears as **“Module: \{project_name\}.app”**), including the dependency below:

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

:::warning
Since **April 2025**, new Google Play policies require **Android API Level 35** for apps to be published or updated on the Google Play Store. Therefore, we strongly recommend using **targetSdkVersion 35** at minimum.
:::

:::info
Using **targetSdkVersion 35** implies using **compileSdkVersion 35**, which in turn triggers some minimum **requirements** for Android ecosystem tools:
* 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 File

To use the SDK, you must add the following configuration to your application’s AndroidManifest.xml:

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

You must also add at least the Internet permission, which is used to send the collected data to QI Tech’s servers:

` `

The list of permissions must be adjusted according to your needs.

---

# Permissions

URL: /en/documentation/caas/device_scan/android/permissions

The SDK collects device data according to the permissions available at the time of collection: the more permissions your app requests and the user grants, the more information can be collected.

:::info **Atenção**

The INTERNET permission is required so the SDK can send information to QI Tech’s servers.
:::

## Permissions used by the SDK

Na versão atual do SDK, as permissões abaixo podem ser utilizadas, caso estejam disponíveis:

| Permissão | Função | Obrigatória |
|------------|--------------|--------------|
|INTERNET|Sends information to QI Tech’s servers.| Yes. |
|BLUETOOTH|Collects information about Bluetooth hardware.| No. |
|BLUETOOTH_CONNECT|Collects Bluetooth connection information.| No. |
|READ_CONTACTS|Reads the contacts list.| No. |
|ACCESS_COARSE_LOCATION|Accesses network information (cell tower, carrier, etc.) and derives location through it (less accurate).| No. |
|ACCESS_FINE_LOCATION|Accesses GPS location (more accurate).| No. |
|READ_PHONE_STATE|Network, SIM, IMEI, and other telephony-related information.| No. |
|QUERY_ALL_PACKAGES|Information about installed apps on the device (required for devices running Android 11 or higher).| No. |

:::info **Important**

Our SDK does not request the permissions listed above. Therefore, to ensure a more complete device scan, we recommend requesting and obtaining these permissions before calling the device scan.
:::

:::info **Attention**

The QUERY_ALL_PACKAGES permission may cause friction with Google Play during app release. To address this, you can provide a justification for requesting this permission.
:::

---

# Authentication

URL: /en/documentation/caas/device_scan/api/authentication

:::danger Aviso Importante!
Starting from version 5.0.0 of the iOS and Android SDKs, the authentication system has been updated to use a temporary token instead of mobileToken.
:::

We use an API Key to allow access to our API. It was likely sent to you by email. If you haven’t received your key yet, email suporte.caas@qitech.com.br .

## Temporary authentication token

Before configuring the SDK, you must generate a temporary token by making a server-to-server request to our API.

### Generate token

```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" }'
```

**Endpoints**

| Environment | URL |
|----------|-----|
| Sandbox | https://d.sandbox.viewpkg.com/device_scan/token |
| Produção | https://d.viewpkg.com/device_scan/token |

**Request Details**

| Field | Type | Required | Description|
|-------|------|------------|---------|
| session_id | string | Yes | Unique session identifier generated by your system (e.g., UUID). |

**Request Body**
```json
{
  "session_id": "unique_session_identifier" (Obrigatório)
}
```

**Response Body**

A successful response will include the `token` field.
```json
{
  "token": "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6..."
}
```

:::info Attention
You must replace EXAMPLE_API_KEY with the API Key provided by support.
:::

---

# The QitechDeviceScan object

URL: /en/documentation/caas/device_scan/flutter/device_scan_object

:::danger Important Note!
As of version 1.0.0, the authentication system has been updated to use a temporary **token** instead of **mobileToken**. The token is obtained by making a server-to-server request to the Device Scan API.
:::

## Request

To use the Device Scan plugin, you must call the `startDeviceScan` method, which has the following parameters:

## Version 1.0.0+

| Parameter | Type | Purpose | Required |
|------------|--------------|--------------|--------------|
|token|String|Temporary authentication token obtained by making a request to the Device Scan API. Must be generated using the same `sessionId` passed to this method.|Yes.|
|environment|CaaSEnvironment|Enum used to configure the runtime environment as `sandbox` or `production`.|Yes.|
|sessionId|String|Key that identifies the session from which the collected data originates. **Must be sent in lowercase.**|Yes.|
|eventType|String|An enum that defines the type of event being reported — care is requested so that very similar events are reported with the same enum, so that intelligence can be built on top of this data.|Yes.|
|eventId|String|An identifier of the event being reported.|Yes.|
|documentNumber|String?|The user's document number, if available. (CPF/CNPJ without dots, dashes, and slash). Can be omitted.|No.|

## Previous Versions (up to 0.x)

| Parameter | Type | Purpose | Required |
|------------|--------------|--------------|--------------|
|mobileToken|String|Customer key that identifies that the collected data comes from your application. If you have not yet received your mobile-token, contact <a href='mailto:suporte.caas@qitech.com.br'>support</a>.|Yes.|
|environment|CaaSEnvironment|Enum used to configure the runtime environment as `sandbox` or `production`.|Yes.|
|sessionId|String|Key that identifies the session from which the collected data originates. **Must be sent in lowercase.**|Yes.|
|eventType|String|An enum that defines the type of event being reported — care is requested so that very similar events are reported with the same enum, so that intelligence can be built on top of this data.|Yes.|
|eventId|String|An identifier of the event being reported.|Yes.|
|documentNumber|String?|The user's document number, if available. (CPF/CNPJ without dots, dashes, and slash). Can be omitted.|No.|

## Quick Reference (Migration)
- 1.0.0+: use temporary `token` obtained via API (`token: token`)
- '`)
- In both: `environment`, `sessionId`, `eventType`, and `eventId` are required. `documentNumber` is optional.

## Return value

The method returns a String to indicate success or failure during information collection:

### Success

```javascript
Success collecting device scan data
```

### Error

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

---

# Implementation

URL: /en/documentation/caas/device_scan/flutter/example

## Prerequisite for startDeviceScan

The `startDeviceScan` method requires a `token`. This token is temporary and must be generated on your backend by making a server-to-server request to our API before you call the SDK method.

**Endpoint Details:**

- **Method:** POST
- **Path:** `/device_scan/token`
- **Sandbox URL:** `https://d.sandbox.viewpkg.com/device_scan/token`
- **Production URL:** `https://d.viewpkg.com/device_scan/token`

**Headers:**

```json
{
  "Authorization": "YOUR_DEVICE_SCAN_API_KEY"
}
```

**Body:**

```json
{
  "session_id": "unique_session_id"
}
```

The successful response from this API will contain the `token` that you must pass to the `startDeviceScan` method.

:::note
The device scan method can be executed asynchronously. Therefore, there is no need to block the main thread to wait for this method to resolve. The user can interact normally with the app while the device scan is being processed in the background.
:::

:::note
We recommend that the device scan method is executed as early as possible. Since it may need more time to collect all data, this early call is recommended so that the most complete device information is extracted.
:::

---

```dart

import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:qitech_device_scan/qitech_device_scan.dart';

final _qitechDeviceScanPlugin = QitechDeviceScan();

// Step 1: Generate the temporary token via a server-to-server request
Future<String?> fetchDeviceScanToken(String sessionId) async {
  final response = await http.post(
    Uri.parse('<DEVICE_SCAN_API_URL>'),
    headers: {
      HttpHeaders.authorizationHeader: '<API_KEY>',
      HttpHeaders.contentTypeHeader: 'application/json',
    },
    body: jsonEncode({'session_id': sessionId}),
  );

  if (response.statusCode == 200) {
    final data = jsonDecode(response.body);
    return data['token'] as String?;
  }
  return null;
}

// Step 2: Initialize the SDK with the obtained token
final sessionId = '<SESSION_ID>';
final token = await fetchDeviceScanToken(sessionId);

if (token == null) {
  print('Failed to fetch device scan token');
  return;
}

final result = await _qitechDeviceScanPlugin.startDeviceScan(
    token: token,
    environment: CaaSEnvironment.sandbox,
    sessionId: sessionId,
    eventType: '<EVENT_TYPE>',
    eventId: '<EVENT_ID>',
);

print('Device Scan result: $result');

```

## Flutter Setup

To use the device scan plugin, the following steps are required:

### Installation

First, run the following command to install the plugin:

```bash
flutter pub add qitech_device_scan
```

The command should install the latest version, which can be checked in your `pubspec.yaml` file:

```yaml
dependencies:
  qitech_device_scan: ^1.0.0
  http: ^1.0.0
```

### Import

Now, just import the package to start using it:

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

## Android Setup

Add the Qi Tech Android repository reference in your `build.gradle` file:

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

Initialize the AdMob service by adding the following code to your `AndroidManifest.xml`:

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

If you do not have an ADMOB_APP_ID, contact suporte.caas@qitech.com.br .

## iOS Setup

Add the Qi Tech iOS repository reference in your `Podfile`:

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

Install dependencies directly via CocoaPods:

```bash
cd ios
pod install
```

or via Flutter:

```bash
flutter build ios
```

---

# Introduction

URL: /en/documentation/caas/device_scan/flutter/introduction

Welcome to the QI Tech Device Scan integration manual for Flutter! You should use our Plugin to collect information from the phone and user behavior in your application, thus improving the accuracy of decisions.

## Having issues?

We are not a company that hides behind an API! Contact our [support](mailto:suporte.caas@qitech.com.br) and we will respond as quickly as possible. Feel free to call us if you want a quick response!

## We love feedback

Even if you have already solved your problem or if it is very simple (even a typo or poor organization that you already understood), send us an email—this way we make the documentation more and more practical and the next person won’t have to suffer the pains you suffered!

## Environments

We have two environments for our customers. The selection is made through an enum passed as a parameter in the plugin call. At the moment, the following environments are available:

* Production - `production`
* Sandbox - `sandbox`

:::danger Important Note!
Real personal and/or business data must not be used in QI Tech’s Sandbox environments.
:::

---

# Permissions

URL: /en/documentation/caas/device_scan/flutter/permissions

The plugin collects the user’s device data according to the permissions available at the time of collection: the more permissions your application requires and the user grants, the more information is collected from the user’s device.

:::info **Attention**

The INTERNET permission is required so the SDK can send information to QI Tech’s servers.
:::

## Permissions used by the plugin

:::info **Important**

Our plugin does not request the permissions described. Therefore, to ensure a more complete device scan, we recommend obtaining these permissions before calling the device scan.
:::

### Android

For the Android platform, the following permissions are used if available:

| Permission             | Purpose                                                                                             | Required |
| ---------------------- | --------------------------------------------------------------------------------------------------- | -------- |
| INTERNET               | Required to send information to QI Tech’s servers.                                                  | Yes.     |
| BLUETOOTH              | Captures Bluetooth hardware information.                                                            | No.      |
| BLUETOOTH_CONNECT      | Captures Bluetooth connection information.                                                          | No.      |
| READ_CONTACTS          | Reads the contacts list.                                                                            | No.      |
| ACCESS_COARSE_LOCATION | Accesses network information (cell tower, carrier...) and location via this method (less accurate). | No.      |
| ACCESS_FINE_LOCATION   | Accesses location via GPS (more accurate).                                                          | No.      |
| READ_PHONE_STATE       | Network, SIM, IMEI, and other telephony-related information.                                        | No.      |
| QUERY_ALL_PACKAGES     | Information about installed apps on the device. Required for Android 11+ devices.                   | No.      |

:::info **Attention**

The QUERY_ALL_PACKAGES permission may cause friction with Google Play during app release. To address this, you can describe the reason for requesting the permission.
:::

### iOS

For the iOS platform, the following permissions are used if available:

* location - Captures device geolocation data

#### Info.plist file

The first step to enable permissions for the plugin is to configure the permission in the app’s Info.plist file, using the following line of code for each desired permission:

* location - Captures device geolocation data:

` NSLocationWhenInUseUsageDescription `
` Add the message you want to show the user when iOS requests permission to access geolocation `

:::info **Attention**

To improve the user experience when requesting permissions, you should customize the message shown in the permission request pop-up as described above.
:::

---

# The QITechIosDeviceScan object

URL: /en/documentation/caas/device_scan/ios/device_scan_object

To use QI Tech’s iOS DeviceScan, you must import the QITechIosDeviceScan framework and then instantiate the QITechIosDeviceScan class, which has the following constructor parameters:

:::danger Important Note!
Starting from version 5.0.0, the authentication system was updated to use a temporary **token**instead of **mobileToken**.
:::

## Version 5.0.0+

| name        | type   | description |
| ----------- | ------ | ---- |
| environment | String | An environment enum where the application is running — `sandbox` or `production`. If a different value is sent, an exception will be thrown. **required**|
| token| String | Authentication token that identifies that the collected data comes from your application. Obtained through a request to the Device Scan API. **required**|
| sessionId   | String | Session identifier (**must be the same used to generate the token**) which will also be sent at the moment of the event evaluation (Transaction, Onboarding, for example), to correlate the device scan data with the event to be evaluated. **required** |

## Previous versions

| name        | type   | description |
| ----------- | ------ | --- |
| environment | String | An environment enum where the application is running — `sandbox` or `production`. If a different value is sent, an exception will be thrown. **required** |
| mobileToken | String | Customer key sent by QI Tech support that identifies that the collected data comes from your application. For security reasons, if this key is incorrect, QI Tech servers will receive the call but will not process it. **required** |
| sessionId   | String | Session identifier, which will also be sent at the moment of the event evaluation (Transaction, Onboarding, for example), to correlate the device scan data with the event to be evaluated. **required**|

---

# Implementation

URL: /en/documentation/caas/device_scan/ios/example

:::danger Important Note!
Starting from version 5.0.0, the authentication system was updated to use a dynamic **token** instead of **mobileToken**. Before configuring the SDK, you must generate a temporary **token** through a server-to-server request to our Device Scan API.
:::

```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")
        }
    }
}
```

To use the iOS Device Scan SDK, the following steps are required:

* Add the required permissions to the Info.plist file
* Add the framework to the app project
* When the app starts, instantiate the library with the appropriate parameters
* If your app has not yet requested the permissions from the user, request them through the `requestPermissions` function of the previously instantiated object
* Collect and send the data using the `collectData` method

---

# Hybrid solutions

URL: /en/documentation/caas/device_scan/ios/hybrid_solutions

In addition to offering native integration in Swift, our SDKs are also compatible with several hybrid frameworks. This is possible through the integration of native plugins specific to each of these frameworks. By leveraging each solution’s native system, it is possible to incorporate our native SDK in the iOS environment.

Some of the most widely used hybrid technologies include 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 para Android](https://docs.unity3d.com/Manual/PluginsForAndroid.html)), Xamarin ([Native Libraries](https://learn.microsoft.com/en-us/xamarin/android/platform/native-libraries)), Appcelerator, Phonegap and Node.

To simplify the integration process with our native solutions, we provide plugins for the React Native and Flutter frameworks. If you’re interested, we provide the documentation and an integration example in our private repositories. For the other hybrid technologies, we have a few examples of how to implement this bridge to the native code. Feel free to contact our support to request access.

---

# Information gathering

URL: /en/documentation/caas/device_scan/ios/information_gathering

To trigger data collection and submission, you must call the `collectData` method. In addition to capturing device information, the method aims to map the customer journey within the application. For this reason, the method also accepts the `eventId` and `eventType` fields. Another important point is that the method sends the information to QI Tech’s server via an asynchronous HTTP request, and therefore the success or error notification for the request is handled through Completion Handlers. The method has the following parameters:

| name             | type           | description |
| ---------------- | -------------- | ----------- |
| documentNumber   | String         | The user’s document number, if available. (CPF/CNPJ without dots, dashes, and slash)|
| eventId          | String         | An identifier of the event being reported|
| eventType        | String         | An enum that defines the type of event being reported (Example: 'login') — Take care to ensure that very similar events are reported with the same enum, so that intelligence can be built on top of this data |
| onSuccessHandler | func() ‑> Void | Function that will be called if the data is successfully sent to QI Tech’s server **required**|
| onErrorHandler   | func() ‑> Void | Function that will be called if there is an error sending the data to QI Tech’s server **required**|

---

# Introduction

URL: /en/documentation/caas/device_scan/ios/introduction

Welcome to the QI Tech iOS Device Scan integration manual! You should use our SDK to collect device information and user behavior data in your application and, in doing so, improve the accuracy of decision-making.

## Having Issues?

We’re not a company that hides behind an API. Get in touch with our [support](mailto:suporte.caas@qitech.com.br) and we’ll respond as quickly as possible. Feel free to call us if you need a faster response!

### We love Feedback

Even if you’ve already solved your issue, or if it’s very simple (even a typo or a poorly organized section), please send us an email. This helps us make the documentation more and more practical, so the next person won’t have to go through the same pain.

## Environments

We provide two environments for our customers. The selection is made through an enum passed into the SDK constructor. Currently, the following environments are available:

* Produção - `production`
* Sandbox - `sandbox`

:::danger Important Note!
Real personal and/or business data must not be used in QI Tech’s Sandbox environments.
:::

---

# Native integration

URL: /en/documentation/caas/device_scan/ios/native_swift

## Remotely

> Starting the installation

```shell
  pod init
```

Our SDK can be imported using CocoaPods.

SDK | Current version
---- | -----
QITechIosDeviceScan | `pod 'QITechIosDeviceScan', '~> 6.0.0'`

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

To start the installation, run the command shown above in the root folder of your project.

> Adding the source to the Podfile

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

The next step is to add QI Tech’s source to the `Podfile`.

> Adding the pod to the Podfile

```ruby
  pod 'QITechIosDeviceScan', '~> <version>'
```
Finally, add the `pod` name following the format above.

:::danger Attention: 
Architecture change (v5.0.0+) Starting from version 5.0.0, the SDK started being distributed exclusively in static form. In your Podfile, you must use the configuration :linkage => :static.
:::

> Podfile example (Version 5.0.0 or higher)

```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 example (Previous versions)

```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 **Attention**

You must enable module stability for the Datadog monitoring dependency to avoid potential compilation issues across different Swift versions. Therefore, add the block described in the post_install section of your Podfile (or include it in the existing post_install block if you already have one).
:::

:::warning Attention
When integrating dependencies on iOS, you may need to use static linkage for some libraries and dynamic linkage for others. This setup is relevant to ensure compatibility, avoid build errors, and optimize project performance.
:::

### Hybrid linkage of dependencies (if needed)

The need for hybrid linkage arises because some libraries have specific requirements: some need static linkage to avoid internal conflicts and symbol duplication, while other dependencies may need dynamic linkage because they are designed for modularity and sharing across projects.

Differences between static and dynamic linkage
* Static (static_framework): The library code is embedded directly into the final binary, reducing runtime loading time and eliminating external dependencies at execution time.
* Dynamic (dynamic_framework): The library is loaded at runtime as a separate file. This reduces the final binary size and makes independent updates/modifications easier.

> Configuring hybrid linkage in the Podfile

```ruby
...

use_frameworks! :linkage => :dynamic # SETTING THE DEFAULT LINKAGE MODE TO DYNAMIC

...

static_frameworks = ['framework_1', 'framework_2', ...] # INCLUDE ALL DEPENDENCIES THAT MUST BE LINKED STATICALY
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
```

> Installing dependencies

```shell
  pod install
```

Finally, run `pod install` to download and install the dependencies.

---

# Permissions

URL: /en/documentation/caas/device_scan/ios/permissions

The SDK collects device data and, according to how the iOS operating system works, it requires specific permissions for each piece of data to be collected. In order to provide a customized experience for users of an application that has the SDK embedded, we implemented a mechanism that uses the parameters passed by the developer to request permissions from the user, following this flow:

* The permissions sent as parameters to the `requestPermissions` method, as Strings, are requested from the user — unless they have already been requested previously.

* The user, through a dialog provided by the operating system itself, is asked about the permissions considered necessary by the framework.

* The permissions are then granted or denied and, when the `collectData` method is called, it will collect only the data for which permission was granted.

:::info **Attention**

If your app has already requested the required permissions, you do not need to call `requestPermissions` again; the SDK will inherit the permissions requested by the app.
:::

## Permissions used by the SDK

In the current SDK version, the following permissions are used if available:

* location - Captures device geolocation data

## Info.plist file

The first step to enable permissions for the SDK is to configure the permission in the app’s Info.plist file, using the following line of code for each desired permission:

* location - Captures device geolocation data:

` NSLocationWhenInUseUsageDescription `
` Add the message you want to display to the user when iOS requests permission to access geolocation `

:::info **Attention**

To improve the user experience when requesting permissions, you should customize the message shown in the permission request pop-up as described above.
:::

---

# Desktop Device Scan

URL: /en/documentation/caas/device_scan/web/desktop

This is the **Desktop Device Scan**, our complementary *white-label* module for the **Web Device Scan**. You can use our program to collect deep device information and also detect the presence of malicious software.

This software was developed to comply with [BCB Normative Instruction No. 491](https://www.bcb.gov.br/estabilidadefinanceira/exibenormativo?tipo=Instru%C3%A7%C3%A3o%20Normativa%20BCB&numero=491). ogether with Web Device Scan, it is able to generate a unique and reliable identification for each device.

:::warning Attention
Our application is *White Label*! You can use your own logos in the installer, as well as customize the executable name and the displayed messages, making the experience friendlier for your user.
:::

## Usage

In this step-by-step guide, you will find details on how to use the program together with the library, as well as a JavaScript implementation example. This will give you the tools you need to adapt the solution to your use case.

```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>
```

When using the `deviceScan.setDesktop(true)` flag, the Web SDK will try to detect whether the installed application is present. If it is not installed or if it has issues, you may receive one of the following errors:

| Error                       | Description                                                                                                                                                                                  |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Timeout in Secure App**   | The application is present but is not responding correctly. Reinstall the application to fix the issue.                                                                                      |
| **Invalid desktop data**    | The application was modified or corrupted. Reinstall the application to restore integrity.                                                                                                   |
| **Desktop App Not Present** | The application is not installed. Provide the download link supplied by QI Tech to the user.                                                                                                 |
| **Unexpected App Error**    | An unexpected error occurred while communicating with the application. If the problem persists after reinstalling, contact support: <a href='mailto:suporte.caas@qitech.com.br'>support</a>. |

## Supported Operating Systems

**Desktop Device Scan** is available for the main modern operating systems, offering native compatibility and optimized performance on each platform.

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

---

# The DeviceScan object

URL: /en/documentation/caas/device_scan/web/device_scan_object

To use the device scan service, you must instantiate the DeviceScan class, which has the following constructor parameters:

| Parameter               | Purpose | Required |
| ----------------------- | ------------------------------------ | -------- |
| `.setSandbox()`         | If this parameter is used in the constructor, the library will be configured to send data to the `sandbox` environment. If omitted, requests are sent to the `production` environment. | No.      |
| `.setGeoLocation(true)` | If this parameter is set to `true`, the library will request permission to collect GPS data. If omitted or set to `false`, geolocation information will not be extracted.              | No.      |

:::info **Attention**
If the user denies access to location data, the library will run normally, but without collecting that information.
:::

## The deviceScan.info() function

To run the user data analysis function, you must send the following parameters to the library. They will identify your company and the user session to which the information belongs. In addition, the event_id and event_type arguments, although optional, help us identify the user’s navigation pattern on your page and therefore prevent fraud even more effectively.

Below are the details for each argument:

| Name       | Type   | Description|
| ---------- | ------ | ----------------------------------- |
| web_token  | String | Customer key that identifies that the collected data comes from your application. If you have not yet received your web-token, contact <a href='mailto:suporte.caas@qitech.com.br'>support</a>. **required** |
| session_id | String | Key that identifies the session from which the collected data originates. **required**|
| event_id   | String | An identifier for the event being reported|
| event_type | String | An enum that defines the type of event being reported — Care is requested so that very similar events are reported with the same enum, so that intelligence can be built on top of this data.|

## Implementation example
A simple implementation example is shown below:

```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>
```

In the example above, a helper function called **callDeviceScan** was created to associate Device Scan usage with a button click. The data collection function can be called twice:

* First, when the user presses the login button, the user’s characteristics and behavior up to that event will be sent to QI Tech’s servers with the identifiers web_token, session_id, event_type ("login"), and event_id ("1").

* Second, when the user presses the buy button, collecting the user’s behavior using the same identifiers web_token (your company) and session_id (your user’s session) but a different event_type ("buy") and event_id ("2"), indicating that a different event has occurred. This maps the entire user journey throughout your website.

---

# Implementation

URL: /en/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>
```

The library performs a user analysis through a call to the **.info()** function, which belongs to the **DeviceScan** class, contained in our **vPkg** library, as shown in the example above. The variables web_token, session_id, event_type (**optional**) and event_id (**optional**) must be replaced with **their actual real values**. On success, the library will return a String indicating successful collection; on failure, it will return a String indicating the error type.

---

# Importing the library

URL: /en/documentation/caas/device_scan/web/import

To import our library, add the URL in a **src** tag in your website’s HTML:

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

---

# Collecting the returns

URL: /en/documentation/caas/device_scan/web/information_gathering

The Web Device Scan SDK returns a _Promise_, which will return a **String** indicating the completion of the flow in success cases.
In error cases, it will return a **String** describing the error. Below is an example of how to map each of these cases and retrieve the results:

```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>
```

### Success return

| Return                        | Description                                                                                         |
| ----------------------------- | --------------------------------------------------------------------------------------------------- |
| Device Scan Successfully Sent | The device scan was performed successfully, as well as the submission of the extracted information. |

### Error return

| Error                 | Description |
| --------------------- | ----------- |
| Web Token Error       | The web token used is invalid. If you are sure you are using the Web Token provided by QI Tech correctly, contact our support ([suporte.caas@qitech.com.br](mailto:suporte.caas@qitech.com.br)) immediately. |
| Invalid Request       | Device information was not collected correctly.|
| Internal Server Error | An unexpected error occurred; check your internet connection.|

---

# Introduction

URL: /en/documentation/caas/device_scan/web/introduction

Welcome to the QI Tech Web Device Scan integration manual! You should use our SDK to collect device information and user behavior data in your application and, in doing so, improve the accuracy of decision-making.

## Having Issues?

We’re not a company that hides behind an API. Get in touch with our [support](mailto:suporte.caas@qitech.com.br) and we’ll respond as quickly as possible. Feel free to call us if you need a faster response!

### We love Feedback

Even if you’ve already solved your issue, or if it’s very simple (even a typo or a poorly organized section), please send us an email. This helps us make the documentation more and more practical, so the next person won’t have to go through the same pain.

## Environments

We provide two environments for our customers. The selection is made through an enum passed into the SDK constructor. Currently, the following environments are available:

* Produção - `production`
* Sandbox - `sandbox`

:::danger Important Note!
Real personal and/or business data must not be used in QI Tech’s Sandbox environments.
:::