# Document Capture

## Available Document Frames

In this camera mode, there is a capture frame to assist the user in positioning the document correctly. After positioning the document correctly, the user should click the button to capture the photo of the document.

{% hint style="warning" %}
The SDK does not perform any type of validation on what is being captured.
{% endhint %}

In this camera mode, it is possible to capture the following documents:

* **RG**: Capture of the RG (separate front and back).
* **CNH**: Capture of the CNH opened.
* **CNH Front**: Capture of the front of the CNH.
* **CNH Back**: Capture of the back of the CNH.
* **CPF**: Capture of the CPF document.
* **Without Silhouette**: Capture of a generic document.

<figure><img src="/files/HLj641ijN8MXnYcrPz4D" alt="" width="375"><figcaption></figcaption></figure>

<br>

## Initializing the SDK

To get started with the Unico IDCloud iOS SDK, import the SDK and implement the `AcessoBioManagerDelegate` interface within the ViewController you wish to use.

The implementation of this class is straightforward and can be done with just a few lines of code. All you need to do is instantiate the *builder* by providing the relevant context and override the callback methods with the business logic of your application:

{% tabs %}
{% tab title="Objective-C" %}

```objectivec
.m:
#import "ViewController.h"
#import <AcessoBio/AcessoBio.h>

@interface ViewController ()
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];   
    unicoCheck = [[AcessoBioManager alloc]initWithViewController:self];
}
   
- (void)onErrorAcessoBioManager:(ErrorBio *)error {
  // Your code
}

- (void)onSystemChangedTypeCameraTimeoutFaceInference {
  // Your code
}

- (void)onSystemClosedCameraTimeoutSession {
  // Your code
}

- (void)onUserClosedCameraManually {
  // Your code
}

@end

```

{% endtab %}

{% tab title="Swift" %}

```swift
import UIKit
import AcessoBio

class ViewController: UIViewController, AcessoBioManagerDelegate {
  var unicoCheck: AcessoBioManager!

  override func viewDidLoad() {
    super.viewDidLoad()
    
    unicoCheck = AcessoBioManager(viewController: self)
  }

  func onErrorAcessoBioManager(_ error: ErrorBio!) {
    // Your code
  }

  func onUserClosedCameraManually() {
    // Your code
  }

  func onSystemClosedCameraTimeoutSession() {
    // Your code
  }

  func onSystemChangedTypeCameraTimeoutFaceInference() {
    // Your code
  }
}   
```

{% endtab %}
{% endtabs %}

## Implementing Callback Functions

Note that, as shown in the previous example, the implementation work of the `AcessoBioManagerDelegate` interface is largely about configuring the callback methods. Each method is called in a specific situation based on the SDK's response.

Simply override the methods illustrated in the previous step with your application's business logic:

{% stepper %}
{% step %}
**`onErrorAcessoBioManager(_ error: ErrorBio!)`**

This method is invoked whenever an implementation error occurs while using any of the methods, such as providing an incorrect document type for the document capture functionality.

When invoked, the method receives a parameter of type `ErrorBio`, which contains details about the error. Learn more about the `ErrorBio` type in the [error handling](https://devcenter.unico.io/idcloud-v2/by-client-integration/sdk/available-sdks/ios-sdk/error-handling-guide) article of this SDK.

{% endstep %}

{% step %}
**`onUserClosedCameraManually()`**

This method is invoked whenever the user manually closes the camera, such as by clicking the "Back" button.

{% endstep %}

{% step %}
**`onSystemClosedCameraTimeoutSession()`**

This method is also invoked once the maximum session time is reached (without capturing any image).

{% hint style="warning" %}
It can be configured in the builder through the **setTimeoutSession** method. This method should receive the maximum session time in seconds. You can modify the maximum session time for your user when using the face detection feature (**Selfie camera with intelligent capture**). If the time limit for capturing the photo is exceeded, you can present a customizable message or instruction to the user. The default value is **40 seconds**, and **the minimum value is also 40 seconds**.
{% endhint %}

{% endstep %}

{% step %}
**`onSystemChangedTypeCameraTimeoutFaceInference()`**

This method is invoked once the maximum time for detecting the user's face is reached (without detecting anything). In this case, the camera mode is automatically switched to manual capture mode (without the intelligent capture silhouette).

{% hint style="warning" %}
The maximum capture time when using face detection (Selfie camera with intelligent capture) is **13 seconds**. If the user faces difficulties capturing the photo using face detection and exceeds the time limit set in the process, the capture automatically switches to manual mode, aiming to facilitate the process for the user (**TimeoutToFaceInference**).
{% endhint %}
{% endstep %}
{% endstepper %}

{% hint style="danger" %}
All of the above methods must be implemented as indicated in your project (even if with no logic). Otherwise, the project will not compile successfully.
{% endhint %}

## Implementing Delegates for Camera Events

The camera opening method (which is called in the next step) needs to know what to do when it **successfully** captures an image or encounters an error during the process. The "actions" to be taken are specified to the camera opening method through the configuration of delegates, which are called in success or error situations.

By configuring the delegates, you can define what happens in your app during error situations (`onErrorDocument` method) or success situations (`onSuccessDocument` method) when capturing images.

To configure the delegates, you need to implement the `DocumentCameraDelegate` and `AcessoBioDocumentDelegate` interfaces:

{% tabs %}
{% tab title="Objective-C" %}

```objectivec
.h:
#import <UIKit/UIKit.h>
#import <AcessoBio/AcessoBio.h>
#import "SelfieCameraDelegate.h"

@interface ViewController: UIViewController <AcessoBioManagerDelegate, DocumentCameraDelegate, 
  AcessoBioDocumentDelegate> {
  AcessoBioManager *unicoCheck;
  // Your code from previous and next steps here
}
```

{% endtab %}

{% tab title="Swift" %}
{% code overflow="wrap" %}

```swift
import UIKit
import AcessoBio

class ViewController: UIViewController, AcessoBioManagerDelegate, DocumentCameraDelegate, 
  AcessoBioDocumentDelegate {    
  // Your code from previous and next steps here
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

### `onSucessDocument` Method

When an image is successfully captured, this method is invoked and returns an object of type `ResultCamera`, which is used later in the REST API request.

{% tabs %}
{% tab title="Objective-C" %}

```objectivec
- (void)onSuccessDocument:(DocumentResult *)result {
    NSLog(@"%@", result.base64);
} 
```

{% endtab %}

{% tab title="Swift" %}

```swift
func onSuccessDocument(_ result: DocumentResult!) {
    // Your code
 }
```

{% endtab %}
{% endtabs %}

The `ResultCamera` object returns two attributes: `base64` and `encrypted`.

* The `base64` attribute can be used if you want to display a preview of the image in your app.
* Both the `encrypted` and `base64` attributes can be sent in the REST API calls of the by Client.

{% hint style="success" %}
If you need to convert the base64 to bitmap, the standard method does not work for Android. You need to split the string at the comma (,) to make it work. If you want to learn more, read the article: [How to convert a Base64 string into a Bitmap image to show it in an ImageView?](https://stackoverflow.com/questions/4837110/how-to-convert-a-base64-string-into-a-bitmap-image-to-show-it-in-a-imageview).
{% endhint %}

### Método `onErrorDocument`

When an error occurs during image capture, this method is invoked and returns an object of type `ErrorBio`.

{% tabs %}
{% tab title="Objective-C" %}

```objectivec
- (void)onErrorDocument:(ErrorBio *)errorBio {
    // Your code
}
```

{% endtab %}

{% tab title="Swift" %}

```swift
func onErrorDocument(_ errorBio: ErrorBio!) {
    // Your code
 }
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Learn more about the `ErrorBio` types in the [error handling](https://devcenter.unico.io/idcloud-v2/by-client-integration/sdk/available-sdks/ios-sdk/error-handling-guide) section of the SDK.
{% endhint %}

## Preparing and Opening the Camera

To open the camera, it is necessary to prepare it using the method `prepareDocumentCamera`. This method takes as a parameter the implementation of the `DocumentCameraDelegate` class and the JSON with the credentials generated in the previous step.

{% tabs %}
{% tab title="Objective-C" %}
{% code overflow="wrap" %}

```objectivec
.h:
#import <UIKit/UIKit.h>
#import <AcessoBio/AcessoBio.h>
#import "SelfieCameraDelegate.h"

@interface ViewController: UIViewController < AcessoBioManagerDelegate,
DocumentCameraDelegate, AcessoBioDocumentDelegate> {
    AcessoBioManager *unicoCheck;
}

.m:
- (IBAction)openCamera:(UIButton *)sender {
    [[unicoCheck build] prepareDocumentCamera:self config:[YourUnicoConfigClass new]];
}
```

{% endcode %}
{% endtab %}

{% tab title="Swift" %}
{% code overflow="wrap" %}

```swift
import UIKit
import AcessoBio

class ViewController: UIViewController, AcessoBioManagerDelegate, 
DocumentCameraDelegate, AcessoBioDocumentDelegate {
    @IBAction func openCamera(_ sender: Any) {
        unicoCheck.build().prepareDocumentCamera(self, config: YourUnicoConfigClass())
    }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

When the camera is ready, the event `onCameraReadyDocument` is triggered, which receives as a parameter an object of type `AcessoBioCameraOpenerDelegate`.

You should override this method, opening the camera with the object received through the `openDocument()` method, receiving the document type parameters to be captured, which are:

| Parameter                 | Description                    |
| ------------------------- | ------------------------------ |
| `DocumentEnums.CPF`       | Capture the front of the CPF   |
| `DocumentEnums.CNH`       | Capture the open CNH           |
| `DocumentEnums.cnhFrente` | Capture the front of the CNH   |
| `DocumentEnums.cnhVerso`  | Capture the back of the CNH    |
| `DocumentEnums.RG`        | Capture the open RG            |
| `DocumentEnums.rgFrente`  | Capture the front of the RG    |
| `DocumentEnums.rgVerso`   | Capture the back of the RGo RG |
| `DocumentEnums.none`      | Capture any other document     |

{% hint style="success" %}
If you need to capture a document for which we don't have a specific frame (e.g., RNE, among others), use the `DocumentEnums.none` frame, which will provide a generic, rectangular frame that can be used to guide any capture.
{% endhint %}

The delegates implemented above (referred to here as Self):

{% tabs %}
{% tab title="Objective-C" %}

```objectivec
- (void)onCameraReadyDocument:(id)cameraOpener {
    [cameraOpener openDocument:DocumentCNH delegate:self];
}

- (void)onCameraFailedDocument:(ErrorPrepare *)message {
  // Your code
}
```

{% endtab %}

{% tab title="Swift" %}

```swift
func onCameraReadyDocument(_ cameraOpener: AcessoBioCameraOpenerDelegate!) {
    cameraOpener.openDocument(DocumentEnums.CNH, delegate: self)
}
 
func onCameraFailedDocument(_ message: ErrorPrepare!) {
  // Your code
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
The `ErrorPrepare` type is an extension of `ErrorBio`, thus containing all its properties. Learn more about the `ErrorBio` type in the SDK [error handling](https://devcenter.unico.io/idcloud-v2/by-client-integration/sdk/available-sdks/ios-sdk/error-handling-guide) section.
{% endhint %}

If an error occurs while preparing the camera, the `onCameraFailedDocument` event is triggered. You should implement this method according to the business logic of your app.

In case of success, the `onSuccessDocument` event is triggered, as explained in the section above.

## Making a POST Request to the Client API

Capturing the images is only the first part of the journey. After capturing the image, you need to send the `base64` generated by the SDK to the by Client REST APIs.&#x20;


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://devcenter.unico.io/unico-idcloud/by-client-integration/sdk/available-sdks/ios-sdk/usage-and-integration-guide/document-capture.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
