> For the complete documentation index, see [llms.txt](https://docs.facephi.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.facephi.com/docs.facephi-pt-br/sdks/sdk-mobile/ios-sdk/modulos/subida-de-ficheros-y-gestion-de-qr.md).

# Envio de arquivos e gerenciamento de QR - Capture

## Introdução

O envio de arquivos e a leitura e geração de códigos QR são realizados com o ***Capture Component***.

Este componente permite o envio de documentos tirando uma foto com a câmera do dispositivo ou a partir da galeria. Suas principais funcionalidades são:

* Envio de documentos pela câmera ou galeria.
* Leitura de códigos QR.
* Geração de códigos QR.

Na seção de [Lançamento simplificado](/docs.facephi-pt-br/sdks/sdk-mobile/ios-sdk/inicializacion/lanzamiento-simplificado.md) são detalhados os passos necessários para a integração básica do SDK. Nesta seção, é adicionada a informação para o lançamento deste componente.

***

## Dependências

Para evitar conflitos e problemas de compatibilidade, caso queira instalar o componente em um projeto que contenha uma versão antiga das bibliotecas da Facephi (Widgets), elas deverão ser removidas completamente antes da instalação dos componentes da **SDKMobile**.

### **CocoaPods**

* Atualmente, as bibliotecas da Facephi são distribuídas remotamente por meio de diferentes gerenciadores de dependências, neste caso CocoaPods. As dependências **obrigatórias** que deverão ter sido instaladas previamente (adicionando-as no arquivo Podfile do projeto) são:

```swift
pod 'FPHISDKMainComponent', '~> $VERSION'
```

* Para instalar o componente de Captura, deve-se incluir a seguinte entrada no Podfile da aplicação:

```swift
pod 'FPHISDKCaptureComponent', '~> $VERSION'
```

### **SPM**

* As dependências obrigatórias que devem ter sido instaladas previamente são:

```swift
//HTTPS
https://github.com/facephi-clienters/SDK-SdkPackage-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-SdkPackage-SPM.git
```

* Para instalar o componente de SelphID, deve-se incluir nos módulos do projeto:

<pre class="language-swift"><code class="lang-swift"><strong>//HTTPS
</strong>https://github.com/facephi-clienters/SDK-CapturePackage-SPM.git
//SSH
git@github.com:facephi-clienters/SDK-CapturePackage-SPM.git
</code></pre>

**IMPORTANTE: Se o FileUploaderController estiver sendo utilizado via SPM. Os recursos e&#x20;*****assets*****&#x20;que o componente precisa requerem a execução de um script em cada compilação do target.**

Para tornar esse processo automático, o script deve ser adicionado em Target -> Build Phases -> + Run Script

```
set -euo pipefail
BUNDLE_PATH="${TARGET_BUILD_DIR}/FPHICaptureWidget-SPM_FPHICaptureWidget-SPM.bundle/compose-resources"
DESTINATION="${TARGET_BUILD_DIR}/${TARGET_NAME}.app/compose-resources"
if [ -d "$BUNDLE_PATH" ]; then
  rm -rf "$DESTINATION"
  mkdir -p "$DESTINATION"
  cp -R "$BUNDLE_PATH/" "$DESTINATION/"
  echo "Copied FPHICaptureWidget Compose resources to ${DESTINATION}"
else
  echo "FPHICaptureWidget Compose resources not found at ${BUNDLE_PATH}. If your app is not using FPHICaptureWidget Component anymore, delete the script from your Build Phases -> Run Script section"
  exit 1
fi

BUNDLE_PATH_DS="${TARGET_BUILD_DIR}/FPHIDesignSystemResources_FPHIDesignSystemResources.bundle/Resources/compose-resources"
DESTINATION="${TARGET_BUILD_DIR}/${TARGET_NAME}.app/compose-resources"
if [ -d "$BUNDLE_PATH_DS" ]; then
  cp -R "$BUNDLE_PATH_DS/" "$DESTINATION/"
  echo "Copied FPHIDesignSystemResources Compose resources to ${DESTINATION}"
else
  echo "FPHIDesignSystemResources Compose resources not found at ${BUNDLE_PATH_DS}. If your app is not using FacePhi Components anymore, delete the script from your Build Phases -> Run Script section"
  exit 1
fi
```

É importante desmarcar a opção *Somente para builds de instalação*.

**Se o script não for adicionado, ocorrerá um crash em tempo de execução quando o FileUploaderController for lançado.**

***

## Controladores disponíveis <a href="#id-3-controladores-disponibles" id="id-3-controladores-disponibles"></a>

| **Controlador**        | **Descrição**                            |
| ---------------------- | ---------------------------------------- |
| FileUploaderController | Controlador para a captura de documentos |
| QrReaderController     | Controlador para a captura de QRs        |
| QrGeneratorController  | Controlador para a geração de QRs        |

***

## Lançamento simplificado <a href="#id-4-lanzamiento-simplificado" id="id-4-lanzamiento-simplificado"></a>

Uma vez iniciado o SDK e criada uma nova operação, será possível lançar o componente. Será possível fazer uso de qualquer um de seus controladores para executar sua funcionalidade.

Lançamento da captura de documentos:

```swift
let controller = FileUploaderController(data: fileUploaderConfigurationData, , output: { sdkResult in
        // Do whatever with the result
        ...
    }, viewController: viewController)
SDKController.shared.launch(controller: controller)
```

Lançamento da captura de QR:

```swift
let controller = QrReaderController(data: qrReaderConfigurationData, , output: { sdkResult in
        // Do whatever with the result
        ...
    }, viewController: viewController)
SDKController.shared.launch(controller: controller)
```

Lançamento da geração de QR:

```swift
let controller = QrGeneratorController(data: qrGeneratorConfigurationData, , output: { sdkResult in
        // Do whatever with the result
        ...
    }, viewController: viewController)
SDKController.shared.launch(controller: controller)
```

***

## Configuração básica <a href="#id-5-configuracion-basica" id="id-5-configuracion-basica"></a>

Para os controladores de captura de componentes e captura de QR, é possível gerar a configuração com os parâmetros padrão. No caso da geração do QR, será necessário o texto que será utilizado:

```
QrGeneratorConfiguration(source:"QR text")
```

***

## Recebimento do resultado <a href="#id-6-recepcion-del-resultado" id="id-6-recepcion-del-resultado"></a>

O lançamento retornará a informação no formato SdkResult.

* errorType
* finishStatus
* data

### Recepção de erros <a href="#id-61-recepcion-de-errores" id="id-61-recepcion-de-errores"></a>

Os erros serão retornados como um objeto 'CaptureError'.

Lista de erros:

* CAP\_ACTIVITY\_RESULT\_MSG\_ERROR: O resultado retornado pela atividade está incorreto ou não contém as informações necessárias para continuar.
* CAP\_APPLICATION\_CONTEXT\_ERROR: O contexto de aplicação necessário está nulo ou inválido, impedindo inicializar corretamente o módulo de captura.
* CAP\_CAMERA\_ERROR: Ocorreu um erro interno relacionado à câmera do dispositivo (falha na abertura, inicialização ou captura).
* CAP\_CAMERA\_PERMISSION\_DENIED: O usuário negou as permissões necessárias para acessar a câmera.
* CAP\_CANCEL\_BY\_USER: O usuário cancelou manualmente o processo de captura.
* CAP\_CANCEL\_LAUNCH: O processo foi cancelado de forma geral pelo SDK ou por uma ação externa.
* CAP\_COMPONENT\_LICENSE\_ERROR: A licença do componente não é válida, expirou ou não corresponde à configuração necessária.
* CAP\_EMPTY\_LICENSE: A cadeia de licença está vazia ou não foi fornecida.
* CAP\_FETCH\_DATA\_ERROR: Ocorreu um erro ao obter ou processar os dados necessários para executar o Fluxo. *(Inclui informações adicionais no campo `error`.)*
* CAP\_FLOW\_ERROR: Ocorreu um erro interno durante a execução do Fluxo de captura. *(Inclui informações adicionais no campo `error`.)*
* CAP\_INITIALIZATION\_ERROR: Erro ao inicializar os componentes necessários do SDK. *(Inclui informações detalhadas no campo `error`.)*
* CAP\_FILE\_UPLOADER\_CAPTURE\_ERROR: Erro durante o processo de envio dos arquivos gerados na captura.
* CAP\_MANAGER\_NOT\_INITIALIZED: Os managers necessários para executar o processo não foram inicializados corretamente.
* CAP\_NO\_DATA\_ERROR: Os dados de entrada necessários estão nulos, inexistentes ou insuficientes para continuar o processo.
* CAP\_OPERATION\_NOT\_CREATED: Não foi possível criar ou recuperar uma operação ativa necessária para continuar. *(Inclui informações detalhadas no campo `error`.)*
* CAP\_QR\_CAPTURE\_ERROR: Erro durante a captura ou leitura do Código QR.
* CAP\_QR\_GENERATION\_ERROR: Erro ao gerar o Código QR solicitado.
* CAP\_TIMEOUT: Foi atingido o tempo máximo permitido em alguma das fases do processo.
* CAP\_FLOW\_VIDEO\_RECORDING\_ERROR: Erro durante a Gravação de Vídeo dentro do Fluxo estabelecido.
* CAP\_FLOW\_TRACKING\_ERROR: Erro ao realizar o Tracking necessário para completar o Fluxo de captura.

### Recebimento do resultado correto - *data* <a href="#id-62-recepcion-del-resultado-correcto-data" id="id-62-recepcion-del-resultado-correcto-data"></a>

#### **Recebimento do resultado da captura de documentos**

Na parte de SdkResult.Success - *data*, teremos a classe *FileUploaderResult*.

Os campos retornados no resultado são os seguintes:

***capturedDocumentList***

Lista de arquivos capturados. Podem ser imagens ou PDFs. Os campos retornados de cada um são:

* mimeType
* timestampMillis
* content: FileContent -> determina se é uma imagem ou um documento PDF. Se for uma imagem, também indica se foi capturada com a câmera ou a partir da galeria.

```
public enum FileContent {
    case uploaderImage(UploaderImage)
    case uploaderDocument(UploaderDocument)
    
    // MARK: - Nested types
    public struct UploaderImage {
        public let image: UIImage
        public let rotationDegrees: Int
        public let source: FileUploaderSource
    }
    
    public struct UploaderDocument {
        public let frontPageImage: UIImage?
        public let bytes: Data
    }
}

public enum FileUploaderSource: String {
    case CAMERA
    case GALLERY
}
```

Por exemplo, para ler o primeiro elemento do array:

```
(..., output: { fileUploaderResult in
    guard fileUploaderResult.errorType == .NO_ERROR else {
        print("\(fileUploaderResult.errorType)")
        return
    }
    ...
    let firstElement = fileUploaderResult.data?.documentImages.first
    
    switch firstElement?.content {
    case .uploaderDocument(let doc):
        // Do something with the file
        break
    case .uploaderImage(let image):
        // Do something with the image
        break
    case .none:
        break
    }
})
```

#### **Recebimento do resultado da captura de QR**

Na parte de SdkResult.Success - *data*, teremos a classe *QrResult*.

Os campos retornados no resultado são os seguintes:

***qrText***

Texto obtido do QR

#### **Recebimento do resultado da geração de QR**

Na parte de SdkResult.Success - *data*, teremos uma SdkImage com o QR criado.

***

## Informações avançadas <a href="#id-7-informacion-avanzada" id="id-7-informacion-avanzada"></a>

Esta seção amplia as informações do componente.

### Configuração avançada do componente <a href="#id-71-configuracion-avanzada-del-componente" id="id-71-configuracion-avanzada-del-componente"></a>

#### **Configuração da captura de documentos**

Para lançar o componente atual, deverá ser criado um objeto *FileUploaderConfigurationData* que será a configuração do controlador do componente.

A seguir, são detalhados todos os campos que fazem parte desta classe.

* `vibrationEnabled`: Indica a ativação da vibração quando o widget for concluído com sucesso.
* `extractionTimeout`: Define o tempo máximo durante o qual a captura pode ser realizada.
* `showDiagnostic`: Mostra telas de diagnóstico ao final do processo.
* `showPreviousTip`: Mostra uma tela anterior ao lançamento da captura com informações sobre o processo a ser realizado e um botão para o lançamento.
* `maxScannedDocs`: Número máximo de documentos que poderão ser capturados
* `allowGallery`: É habilitado o acesso à galeria para a obtenção de imagens ou PDFs
* `onlyGalleryMode`: Abre o Fluxo diretamente no modo galeria, sem exibir a captura com câmera. Por padrão `true`.
* `maxGalleryImageSizeKb`: Tamanho máximo permitido para imagens selecionadas da galeria, em KB. Por padrão `2048`. Se uma imagem exceder esse limite, o componente retorna `CAP_IMAGE_TOO_LARGE`.

#### **Configuração da captura de QR**

Para lançar o componente atual, deverá ser criado um objeto *QrCaptureConfigurationData* que será a configuração do controlador do componente.

A seguir, são detalhados todos os campos que fazem parte desta classe.

* `vibrationEnabled`: Indica a ativação da vibração quando o widget for concluído com sucesso.
* `extractionTimeout`: Define o tempo máximo durante o qual a captura pode ser realizada.
* `showDiagnostic`: Mostra telas de diagnóstico ao final do processo.
* `showPreviousTip`: Mostra uma tela anterior ao lançamento da captura com informações sobre o processo a ser realizado e um botão para o lançamento.
* `showTutorial`: Indica se o componente ativa a tela de tutorial. Nessa visualização, é explicado de forma intuitiva como a captura é realizada.
* `cameraShape`: Permite escolher entre uma máscara quadrada e uma redonda.

***

## Personalização do componente <a href="#id-8-personalizacion-del-componente" id="id-8-personalizacion-del-componente"></a>

Além das alterações que podem ser feitas no nível do SDK (as quais são explicadas no documento de *Personalização do SDK*), este componente em específico permite a modificação da sua interface.

### Textos <a href="#id-81-textos" id="id-81-textos"></a>

Os textos podem ser personalizados sobrescrevendo o valor das seguintes chaves em um **Localizable.strings**. As chaves que contêm o sufixo ***\_alt*** são os literais usados nos rótulos de acessibilidade necessários para a funcionalidade de ***VoiceOver***.

```xml
<resources>
    <!-- Dica anterior -->
    <string name="capture_component_qr_tip_title">Escaneie o código QR</string>
    <string name="capture_component_qr_tip_message">&lt;b&gt; Aponte &lt;/b&gt; o código QR &lt;b&gt; dentro do quadro &lt;/b&gt;</string>
    <string name="capture_component_qr_tip_button">Começar</string>
    <string name="capture_component_qr_tip_anim_desc">Animação de um telefone celular tirando uma foto de um código QR. Na tela do celular aparece um quadro. Quando o código QR se encaixa dentro do quadro, o aplicativo tira uma foto.</string>
    <string name="capture_component_qr_tutorial_1_anim_desc">É mostrado um código QR sobre um fundo branco. As bordas do código QR não são distinguidas com clareza. Por meio de uma animação, o fundo muda de cor.</string>
    <string name="capture_component_qr_tutorial_2_anim_desc">Um telefone celular tira uma foto de um código QR. O código QR aparece na horizontal, e o celular na posição vertical. Na tela do celular aparece um quadro. Quando o código QR se encaixa dentro do quadro, o aplicativo tira uma foto.</string>
    <!-- Tutorial -->
    <string name="capture_component_qr_tutorial_1">Certifique-se de que o código QR tem &lt;b&gt; luz suficiente &lt;/b&gt; e &lt;b&gt; não há reflexos &lt;/b&gt; ou brilhos sobre o código.</string>
    <string name="capture_component_qr_tutorial_2">Encaixe as bordas do código QR dentro do quadro.</string>
    <!-- Process -->
    <string name="capture_component_qr_camera_message">Mantenha o QR no centro</string>
    <string name="capture_component_button_message">Capturar</string>
    <!-- Diagnostic -->
    <string name="capture_component_timeout_title">Tempo esgotado</string>
    <string name="capture_component_timeout_desc">Pedimos desculpas. Não foi possível fazer a captura</string>
    <string name="capture_component_internal_error_title">Houve um problema técnico</string>
    <string name="capture_component_internal_error_desc">Pedimos desculpas. Não foi possível fazer a captura</string>

    <!-- WIDGET -->
    <!-- Dica anterior -->
    <string name="capture_widget_tip_title">Escanear documentos</string>
    <string name="capture_widget_tip_message">Tire uma foto do documento, ou envie uma imagem.&lt;br&gt;&lt;br&gt; Você pode escanear vários documentos antes de finalizar.</string>
    <string name="capture_widget_tip_message_alt">Tire uma foto do documento, ou envie uma imagem. Você pode escanear vários documentos antes de finalizar.</string>
    <string name="capture_widget_tip_button">Começar</string>
    <string name="capture_widget_tip_button_alt">Começar captura de documentos</string>
    <string name="capture_widget_tip_close_button_alt">Voltar</string>
    <string name="capture_widget_tip_info_button_alt">Ver dicas</string>
    <string name="capture_widget_tip_anim_desc">Animação de um telefone celular tirando uma foto de um documento. Na tela do celular aparece um quadro. Quando o documento se encaixa dentro do quadro, o aplicativo tira uma foto.</string>
    <!-- Camera -->
    <string name="capture_widget_document_camera_button_gallery">Galeria</string>
    <string name="capture_widget_document_camera_button_capture">Capturar</string>
    <string name="capture_widget_document_camera_button_cancel">Cancelar captura</string>
    <string name="capture_widget_document_camera_button_finish">Finalizar</string>
    <!-- Gallery -->
    <string name="capture_widget_gallery_images">Imagens</string>
    <string name="capture_widget_gallery_pdf">Selecionar PDF</string>
    <string name="capture_widget_gallery_cancel">Cancelar</string>
    <!-- Confirmation -->
    <string name="capture_widget_image_captured">Imagem capturada</string>
    <string name="capture_widget_confirmation_message">Todos os dados são lidos de forma clara e nítida?</string>
    <string name="capture_widget_confirmation_retry">NÃO, QUERO REPETIR AS FOTOS</string>
    <string name="capture_widget_confirmation_continue">Sim, finalizar</string>
    <string name="capture_widget_confirmation_delete">Excluir foto</string>
    <string name="capture_widget_confirmation_image_unavailable">Pré-visualização não disponível</string>
    <string name="capture_widget_confirmation_no_images">Não há capturas disponíveis</string>
    <string name="capture_widget_confirmation_delete_dialog_title">Deseja excluir este documento?</string>
    <string name="capture_widget_confirmation_delete_dialog_message">Ao excluir este documento, você não poderá recuperá-lo. Será necessário tirar uma nova foto.</string>
    <string name="capture_widget_confirmation_delete_dialog_cancel">CANCELAR</string>
    <string name="capture_widget_confirmation_delete_dialog_confirm">EXCLUIR DOCUMENTO</string>
    <!-- Diagnostic -->
    <string name="capture_widget_timeout_title">Tempo esgotado</string>
    <string name="capture_widget_timeout_desc">Pedimos desculpas. Não foi possível fazer a captura</string>
    <string name="capture_widget_internal_error_title">Houve um problema técnico</string>
    <string name="capture_widget_internal_error_desc">Pedimos desculpas. Não foi possível fazer a captura</string>

</resources>
```

Dessa forma, se desejar modificar, por exemplo, o texto “*Começar*” da chave `capture_widget_tip_button` para o idioma **é**, deve-se ir ao arquivo **Localizable.strings** da pasta **es.lproj** se existir (se não, deverá ser criado) e, então, adicionar:

`"capture_widget_tip_button"="Start";`

Se uma mensagem não for especificada no arquivo do idioma, ela será preenchida com a mensagem padrão.

### Animações <a href="#id-82-animaciones" id="id-82-animaciones"></a>

Se desejar modificar as animações (lottie) do SDK, seria necessário incluir as animações com o mesmo nome na pasta res/raw/ da aplicação.

```
qr_anim_tip_1.json
qr_anim_tip_2.json
capture_anim_tip.json
```
