> 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, amplia-se a informação do item [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, indica-se como preparar o ambiente para consumir os componentes:

* Primeiro, instalamos o comando que nos dará acesso para 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
```

Caso haja 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. A indentação antes das palavras **login** e **password** é composta 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 requeridas 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 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 se 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**, existe a possibilidade de que a instalação do cocoapods-art não seja realizada corretamente. Por isso, devem ser considerados os seguintes pontos:

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

A seguir, incluímos um script que permite realizar todas as etapas necessárias 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. As etapas a seguir na inicialização são:

1. Inicializar os controladores que serão utilizados.
2. Decidir se a licença será incluída como `String` ou por meio de um serviço de licenciamento remoto (consultar [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("ERRO DE TRACKING: \(trackingError)")
})

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

// AUTO License
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 configurada 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 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 uma API-KEY como identificador. Isso evitaria problemas ao manipular a licença, bem como a substituição constante dessas licenças caso surja algum problema com ela (malformação ou modificação indevida, expiração da licença...)

```swift
// AUTO License
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 configurada corretamente")
    } else {
        self.log("Ocorreu um erro ao tentar obter a licença: \(sdkResult.errorType)")
    }
}, trackingController: trackingController)
```

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

É possível atribuir a licença diretamente como uma String, da seguinte maneira:

```swift
// MANUAL License
SDKController.shared.initSdk(license: SdkConfigurationManager.LICENSE, output: { sdkResult in
    if sdkResult.finishStatus == .STATUS_OK {
        self.log("Licença manual configurada 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 ela vai começar, e assim o SDK saberá que as próximas chamadas de **Componentes** (também chamados de **Steps**) farão parte dessa operação. Isso é necessário para rastrear para a plataforma as informações globais dessa operação de forma satisfatória.

Ao iniciar um processo ou Fluxo, **sempre** deverá ser feita a chamada ao método **newOperation**

Este método possui 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 no nível da aplicação)
3. **steps**: Lista de etapas da operação, caso tenham sido definidas previamente

Há 2 maneiras de realizar esse início de operação, dependendo se **as etapas são conhecidas** que formarão o Fluxo do processo de cadastro ou autenticação (caso os componentes sejam executados de forma sequencial e sempre da mesma maneira) 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** os componentes do SDK associados a esta operação poderão ser executados. 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 passos:

| **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 será ampliada nas próximas atualizações do SDK, à medida que novos componentes e casos de uso forem surgindo.

### 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:

* **\[COM Tracking]** Lança o componente e **envia eventos** ao servidor de *Tracking*:

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

* **\[SEM Tracking]** Lança o componente **sem enviar eventos** ao servidor de *Tracking*:

```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 ***Tracking*** caso o seu componente esteja ativado, e não será usado quando estiver desativado (ou se o componente não estiver instalado).

Por outro lado, o método **launchMethod** cobre um caso especial, no qual o integrador tem o Tracking instalado e ativado, mas em um Fluxo determinado dentro do aplicativo 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 da 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 houve um erro, este campo terá 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 estão incluídos outros controladores e operações auxiliares, alguns deles opcionais, e que podem ser necessários 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 *Tracking* 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)
```
