> 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/ajustes-avanzados.md).

# Configurações avançadas

Nesta seção, a informação do item é ampliada [Lançamento simplificado](/docs.facephi-pt-br/sdks/sdk-mobile/ios-sdk/inicializacion/lanzamiento-simplificado.md).

### Adicionar repositório privado

Para ter acesso ao nosso repositório privado, é necessário ter instalado previamente **CocoaPods** na máquina.

Por questões de segurança e manutenção, os novos componentes da ***SDKMobile*** são armazenados em alguns repositórios privados que exigem credenciais específicas para poder acessá-los. Essas credenciais deverão ser obtidas por meio da equipe de suporte da Facephi. A seguir, é indicado como preparar o ambiente para consumir os componentes:

* Primeiro instalamos o comando que nos dará acesso a usar CocoaPods com **Artifactory**.

```
sudo gem install cocoapods-art
```

* Em um Mac com **chip M1** podem surgir erros durante a instalação; nesse caso, use o seguinte comando:

```
sudo arch -arm64 gem install ffi; sudo arch -arm64 gem install cocoapods-art
```

Em caso de problemas com a instalação, desinstale completamente o CocoaPods e todas as suas dependências para fazer uma instalação limpa.

* Precisaremos adicionar o repositório à lista do arquivo **netrc**. Para isso, a partir de um Terminal, execute o seguinte comando:

```
$ nano ~/.netrc
```

E copiamos o seguinte fragmento com os dados correspondentes ao final do arquivo:

```
machine facephicorp.jfrog.io
  login <USERNAME>
  password <TOKEN>
```

É importante copiar de maneira **exata** o fragmento de código anterior. O recuo antes das palavras **login** e **password** é formado por dois espaços.

* Por fim, será adicionado o repositório que contém dependências privadas:

```
pod repo-art add cocoa-pro-fphi "https://facephicorp.jfrog.io/artifactory/api/pods/cocoa-pro-fphi"
```

### Dependências necessárias para a Integração <a href="#id-22-dependencias-requeridas-para-la-integracion" id="id-22-dependencias-requeridas-para-la-integracion"></a>

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

* Atualmente, as bibliotecas FacePhi são distribuídas remotamente por meio de diferentes gerenciadores de dependências, neste caso, ***CocoaPods***. **Dependências obrigatórias** que devem ser instaladas previamente (adicionando-as ao *Podfile*):

```ruby
plugin 'cocoapods-art', :sources => [
  'cocoa-pro-fphi'
]

source 'https://cdn.cocoapods.org/'

target 'Example' do
  pod 'FPHISDKMainComponent', '~> $VERSION'

  post_install do |installer|
    installer.pods_project.targets.each do |target|
      target.build_configurations.each do |config|
        config.build_settings['EXPANDED_CODE_SIGN_IDENTITY'] = ""
        config.build_settings['CODE_SIGNING_REQUIRED'] = "NO"
        config.build_settings['CODE_SIGNING_ALLOWED'] = "NO"
      end
    end
  end
end
```

* Quando quiser atualizar dependências, antes de executar **`pod install`** use o seguinte comando para atualizar o repositório local:

```sh
pod repo-art update cocoa-pro-fphi
```

### Possíveis problemas <a href="#id-23-posibles-incidencias" id="id-23-posibles-incidencias"></a>

No caso de o integrador utilizar um MacBook com chip **M1**, há a possibilidade de que a instalação de cocoapods-art não seja realizada corretamente. Portanto, devem ser levados em conta os seguintes pontos:

* Se o cocoapods tiver sido instalado via Homebrew, podem ocorrer problemas.
* Recomenda-se instalar cocoapods e cocoapods-art usando gem.

A seguir, incluímos um script que permite realizar todos os passos necessários para deixar o ambiente preparado para funcionar corretamente:

```
 #! /bin/zsh

install_cocoapods () {
    echo "Installing cocoapods with gem"
    # Creating new gems home if it doesnt't exist
    if [ ! -d "$HOME/.gem" ]; then
        mkdir "$HOME/.gem"
    fi
    # Adding to current session
    export GEM_HOME="$HOME/.gem"
    export PATH="$GEM_HOME/bin:$PATH"

    # Adding for future sessions
    if test -f "$HOME/.zshrc"; then
        echo 'Adding $GEM_HOME env var and then adding it to your $PATH'
        echo '' >> "$HOME/.zshrc"
        echo 'export GEM_HOME="$HOME/.gem"' >> "$HOME/.zshrc"
        echo 'export PATH="$GEM_HOME/bin:$PATH"' >> "$HOME/.zshrc"
        echo 'alias pod="arch -x86_64 pod"' >> "$HOME/.zshrc"
    fi

    # Installing cocoapods
    gem install cocoapods
    sudo arch -x86_64 gem install ffi
    which pod
    pod --version
    gem install cocoapods-art
}

uninstall_cocoapods_homebrew () {
    which -s brew
    if [[ $? != 0 ]] ; then
        echo "Homebrew not installed, skipping uninstalling cocoapods from homebrew"
    else
        brew uninstall cocoapods
    fi
}

if ! type "pod" > /dev/null; then
    echo "You don't have cocoapods installed..."
else
    echo "Trying to uninstall it from homebrew first"
    uninstall_cocoapods_homebrew
fi

install_cocoapods
```

Caso use ***xCode15*** deverá ser feita a seguinte configuração:

<figure><img src="/files/ff987c2244f7b43824af77b6aaf968fef350fc02" alt=""><figcaption></figcaption></figure>

Deverá ser adicionado ***-ld\_classic*** em Other Linker Flags, nas Build Settings da aplicação.

### Inicialização do SDK <a href="#id-3-sdk-initialization" id="id-3-sdk-initialization"></a>

**Deve-se evitar inicializar um controlador que não será usado.**

Cada um dos componentes tem um controlador (*Controller*) que permitirá acessar sua própria funcionalidade. Antes de poder ser utilizado, deverá ser inicializado corretamente. Os passos a seguir na inicialização são:

1. Inicializar os controladores que serão usados.
2. Decidir se a Licença será incluída como `String` ou por meio de um serviço de licenciamento remoto (consulte [Injeção de licenças](#id-31-inyeccion-de-licencias)) e invocar a Inicialização do SDK.
3. Se a Inicialização retornar `FinishStatus.STATUS_OK`, o SDK estará pronto para uso.

```swift
let trackingController = TrackingController(trackingError: { trackingError in
    self.log("TRACKING ERROR: \(trackingError)")
})

// Licença manual
SDKController.shared.initSdk(license: SdkConfigurationManager.LICENSE, output: { sdkResult in
    if sdkResult.finishStatus == .STATUS_OK {
        self.log("Licença manual definida corretamente")
    } else {
        self.log("A licença manual não está correta")
    }
}, trackingController: trackingController)

// Licença automática
SDKController.shared.initSdk(
    licensingUrl: SdkConfigurationManager.LICENSING_URL,
    apiKey: SdkConfigurationManager.APIKEY_LICENSING,
    output: { sdkResult in
        if sdkResult.finishStatus == .STATUS_OK {
            self.log("Licença automática definida corretamente")
        } else {
            self.log("Ocorreu um erro ao tentar obter a licença: \(sdkResult.errorType)")
        }
    },
    trackingController: trackingController)
```

#### Injeção de licenças <a href="#id-31-inyeccion-de-licencias" id="id-31-inyeccion-de-licencias"></a>

Como foi comentado anteriormente, atualmente existem duas formas de injetar a licença:

**a. Obtendo a licença por meio de um serviço**

Por meio de um serviço que simplesmente exigirá uma URL e um API-KEY como identificador. Isso evitaria problemas na hora de manipular a licença, assim como a constante substituição dessas licenças quando surgisse algum problema com ela (malformação ou modificação indevida, expiração da licença...)

```swift
// Licença automática
SDKController.shared.initSdk(licensingUrl: SdkConfigurationManager.LICENSING_URL, apiKey: SdkConfigurationManager.APIKEY_LICENSING, output: { sdkResult in
    if sdkResult.finishStatus == .STATUS_OK {
        self.log("Licença automática definida corretamente")
    } else {
        self.log("Ocorreu um erro ao tentar obter a licença: \(sdkResult.errorType)")
    }
}, trackingController: trackingController)
```

**b. Injetando a licença como String**

A licença pode ser atribuída diretamente como um String, da seguinte forma:

```swift
// Licença manual
SDKController.shared.initSdk(license: SdkConfigurationManager.LICENSE, output: { sdkResult in
    if sdkResult.finishStatus == .STATUS_OK {
        self.log("Licença manual definida corretamente")
    } else {
        self.log("A licença manual não está correta")
    }
}, trackingController: trackingController)
```

### Iniciar nova operação <a href="#id-4-iniciar-nueva-operacion" id="id-4-iniciar-nueva-operacion"></a>

Sempre que se desejar iniciar o Fluxo de alguma nova operação (exemplos de operações seriam: onboarding, authentication, videoCall,…) é essencial informar ao **SDKController** que esta vai começar, e assim o SDK saberá que as próximas chamadas de **Componentes** (também chamados **Steps**) farão parte dessa operação. Isso é necessário para monitorar na plataforma as informações globais dessa operação de forma satisfatória.

Ao iniciar um processo ou Fluxo, **sempre** será necessário realizar a chamada ao método **newOperation**

Este método tem 3 parâmetros de entrada:

1. **operationType**: Indica se será realizado um processo de Onboarding ou de Authentication
2. **customerId**: ID único do usuário, se houver (controlado em nível de aplicação)
3. **steps**: Lista de etapas da operação, se tiverem sido definidas previamente

Há 2 maneiras de realizar este início de operação, dependendo de se **conhecem os passos** que formarão o Fluxo do processo de registro ou autenticação (no caso de os componentes serem executados de forma sequencial e sempre da mesma forma) ou, caso contrário, de que o Fluxo **não esteja definido** e seja desconhecido (por exemplo, o cliente final é quem decide a ordem de execução dos componentes).

* Fluxo **conhecido** (a operação rastreada aparecerá na plataforma com todos os passos da lista). Exemplo de implementação:

```swift
SDKController.shared.newOperation(
    operationType: OperationType.X,
    customerId: "customerId",
    steps: [.SELPHI, .SELPHID, .OTHER("CUSTOM_STEP")],
    output: { _ in })
```

* Fluxo **desconhecido** (a operação rastreada aparecerá na plataforma com reticências). Exemplo de implementação:

```swift
SDKController.shared.newOperation(
    operationType: OperationType.X,
    customerId: "customerId",
    output: { _ in })
```

Em **`SdkResult.Success`**, o campo **`data`** contém as informações da operação criada.

**Uma vez criada a operação** poderão ser executados os componentes da SDK associados a esta operação. Consulte a documentação específica de cada componente para saber como fazer isso.

#### Tipos de operação existentes <a href="#id-41-tipos-de-operacion-existentes" id="id-41-tipos-de-operacion-existentes"></a>

Atualmente, existem as seguintes operações, durante as quais são usados determinados **Componentes (STEPS)**. A seguir, é mostrada uma tabela com a relação entre operações e steps:

| **Operação (OperationType)** | **Componente (Step)**                          | Descrição                                                                                                                            |
| ---------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| ONBOARDING                   | <p>SELPHI\_COMPONENT<br>SELPHID\_COMPONENT</p> | <p>- Validação facial de uma selfie contra o rosto de um documento<br>- Extração do OCR do documento<br>- Detecção de vivacidade</p> |
| AUTHENTICATION               | SELPHI\_COMPONENT                              | <p>- Validação facial por meio de templates<br>- Detecção de vivacidade</p>                                                          |

Esta lista irá sendo ampliada em próximas atualizações do SDK, conforme forem surgindo novos componentes e casos de uso.

### Opções para o lançamento do componente

Uma vez iniciado o SDK e criada uma nova operação, será possível lançar o componente. Há duas formas de lançar o componente:

* **\[CON TRACKING]** Inicia o componente e **envia eventos** ao servidor de *rastreamento*:

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

* **\[SEM TRACKING]** Inicia o componente **sem enviar eventos** ao servidor de *rastreamento*:

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

O método **launch** deve ser usado **por padrão**. Este método permite utilizar ***rastreamento*** caso seu componente esteja ativado, e não será usado quando estiver desativado (ou quando o componente não estiver instalado).

Por outro lado, o método **launchMethod** abrange um caso especial, no qual o integrador tem o Tracking instalado e ativado, mas em um Fluxo determinado dentro da aplicação não deseja rastrear informações. Nesse caso, usa-se este método para evitar que essas informações sejam enviadas para a plataforma.

### Retorno do resultado <a href="#id-6-retorno-de-resultado" id="id-6-retorno-de-resultado"></a>

O resultado de cada componente será retornado por meio do SDK, mantendo sempre a mesma estrutura de 3 campos:

1. **finishStatus**: Que nos indicará se a operação foi finalizada corretamente. Valores possíveis `FinishStatus.STATUS_OK`, `FinishStatus.STATUS_ERROR`
2. **errorType**: Se *finishStatus* indica que ocorreu um erro, este campo conterá a descrição dele.
3. **data**: Dados de resposta do SDK; sua estrutura depende do componente executado (veja a documentação de cada módulo).

### Métodos auxiliares <a href="#id-6-controladores-auxiliares" id="id-6-controladores-auxiliares"></a>

Nesta seção, incluem-se outros controladores e operações auxiliares, algumas delas opcionais, e que podem ser necessárias para a correta finalização do Fluxo.

Esses campos são necessários para a comunicação com o serviço de **Facephi**, caso se queira realizar qualquer **verificação** e desejar realizar o *rastreamento* de uma operação determinada.

#### Obtenção do OperationId <a href="#id-61-obtencion-del-operationid" id="id-61-obtencion-del-operationid"></a>

```swift
SDKController.shared.getOperationId()
```

#### Obtenção do OperationType <a href="#id-62-obtencion-del-operationtype" id="id-62-obtencion-del-operationtype"></a>

```swift
SDKController.shared.getOperationType()
```

#### Obtenção do SessionId <a href="#id-63-obtencion-del-sessionid" id="id-63-obtencion-del-sessionid"></a>

```swift
SDKController.shared.getSessionId()
```

#### Obtenção do CustomerID <a href="#id-64-obtencion-del-customerid" id="id-64-obtencion-del-customerid"></a>

```swift
SDKController.shared.getCustomerId()
```

#### Atribuição do CustomerID <a href="#id-65-asignacion-del-customerid" id="id-65-asignacion-del-customerid"></a>

```swift
SDKController.shared.setCustomerId(customerId: customerId)
```
