Guia Detalhado de Uso

Aprofunde seu entendimento e personalize com precisão, com explicações completas que orientam cada etapa do processo.

📑 Sumário

  1. 📌 Visão Geral
  2. ✅ Requisitos de Compatibilidade
  3. ⚙️ Instalação
  4. 🔌 Criação do provedor de Liveness
    4.1 ✅ Provedores Disponíveis
    4.2 🧩 Provedor: IProov
  5. 📦 Estrutura das Classes Importantes
  6. 🔍 Principais Classes e Métodos de Chamada
  7. 📱 Fluxo de Telas
    7.1 📝 Tela Inicial/Instruções
    7.2 📷 Tela de Permissão de Câmera
    7.3 🙂 Tela de Liveness
    7.4 🔄 Tela de Processamento
    7.5 ✅ Tela de Resultado
  8. 🧪 Ambiente de Testes
  9. 🛠️ Boas Práticas
  10. 📜 Changelogs e Versões

📌 Visão Geral

O Oiti SDK é um SDK modular e extensível, responsável por oferecer verificação facial remota (Liveness Detection) via múltiplos provedores de biometria.

Sua arquitetura foi desenvolvida com foco em segurança, personalização e abstração de provedores, permitindo que novos fornecedores sejam incorporados no futuro com impacto mínimo na integração.

⚠️

Atualmente temos suporte ao provedor IProov, mas em breve outros serão incorporados ao SDK.


✅ Requisitos de Compatibilidade

  • Target mínimo: iOS 13.0

  • Versão do Swift: 5+

  • Linguagem base: Swift (interoperável com Objective-C)

  • Gerenciador de dependência: CocoaPods

  • Ambientes suportados:

    • hml: Homologação
    • prd: Produção

⚙️ Instalação

Passo 1: Caso você não possua um arquivo Podfile no seu projeto, basta executar o comando abaixo na raiz do projeto que um novo arquivo desse será criado:

pod init

Passo 2: No início do Podfile, inclua a linha abaixo:

source 'https://github.com/oititec/ios-artifactory.git'

Passo 3: Em seguida, adicione as dependências necessárias:

pod 'OitiSDK', '~> x.y.z'

Substitua x.y.z pela versão mais recente fornecida pela Oiti.

Passo 4: Execute o comando de instalação dos pods:

pod install

🔌 Criação do provedor de Liveness

O OitiSDK utiliza o padrão de fábrica para criar instâncias específicas de cada provedor de Liveness:

let manager = OitiSDKFactory.createLivenessManager(for: .iproov)

✅ Provedores Disponíveis

ProvedorIdentificador EnumSuporte
IProovLivenessProvider.iproov✅ Suporte Atual
[Novo Provedor]em breve🔜 Planejado

🧩 Provedor: IProov

Este é o provedor atualmente integrado ao SDK. Ele oferece uma jornada de verificação baseada em luz e detecção passiva.

🚀 Execução da Jornada

Após criar o LivenessManagerOptions fornecendo a AppKey, o ambiente de execução, as telas customizadas e a customização do IProov, inicie a jornada com:

import OitiSDK

// MARK: - Implementação

final class ContentViewController: UIViewController {
    func executeLiveness() {
        let options = LivenessManagerOptions
            .builder(appKey: "APP_KEY", environment: .hml)
            .build()

        let manager = OitiSDKFactory.createLivenessManager(for: .iproov)
        manager.start(at: self, options: options, callback: self)
    }
}

extension ContentViewController: LivenessCallback {
    func onSuccess(_ result: LivenessResult) {
        // Código ...
    }

    func onError(_ error: LivenessError) {
        // Código ...
    }
}
  

🎨 Personalização Visual

Utilize o builder da classe IProovLivenessCustomization para configurar a interface do fluxo.

UIViews customizadas

O SDK permite customizar completamente as telas presentes na jornada (exceto a tela de Liveness), para tal é necessário que as UIViews estejam em conformidade com os protocolos destinados a cada tela:

import OitiSDK

// MARK: - Views customizadas

final class LivenessCustomInstructionViewImpl: UIView, LivenessCustomInstructionView {
    var backButton: UIButton!
    var continueButton: UIButton!

    func changeLoadingVisibility(to visibility: Visibility) {
        // Código ...
    }
}

final class CustomCameraPermissionViewImpl: UIView, CustomCameraPermissionView {
    var backButton: UIButton!
    var checkPermissionButton: UIButton!
    var openSettingsButton: UIButton!
    var closeButton: UIButton!

    func showBottomSheet(visibility: OitiSDK.Visibility) {
        // Código ...
    }
}

final class IProovCustomLoadingViewImpl: IProovCustomLoadingView {
    // Código ...
}

final class IProovCustomResultViewImpl: IProovCustomResultView {
    func display(for resultType: IProovResultLayoutType) {
        // Código ...
    }
}

// MARK: - Implementação

final class ContentViewController: UIViewController {
    func executeLiveness() {
        let customization = IProovCustomization.builder()
            .setCustomInstructionView(LivenessCustomInstructionViewImpl())
            .setCustomCameraPermissionView(CustomCameraPermissionViewImpl())
            .setLoadingView(IProovCustomLoadingViewImpl())
            .setResultView(IProovCustomResultViewImpl())
            .build()

        let options = LivenessManagerOptions
            .builder(appKey: "APP_KEY", environment: .hml)
            .setIProovCustomization(customization)
            .build()

        let manager = OitiSDKFactory.createLivenessManager(for: .iproov)
        manager.start(at: self, options: options, callback: self)
    }
}

extension ContentViewController: LivenessCallback {
    func onSuccess(_ result: LivenessResult) {
        // Código ...
    }

    func onError(_ error: LivenessError) {
        // Código ...
    }
}
  

Aparência customizada

O SDK permite customizar somente as características das telas da jornada mantendo a estrutura padrão:

import OitiSDK

// MARK: - Implementação

final class ContentViewController: UIViewController {
    func executeLiveness() {
        let customization = IProovCustomization.builder()
            .setInstructionCustomization { instructionBuilder in
                instructionBuilder
                    .setBackgroundColor(.purple)
                    .setBackButtonIcon(UIImage(systemName: "trash") ?? UIImage())
                    .setBackButtonColor(forContent: .red, background: .green, border: .white)
                    .setContextImage(UIImage(systemName: "person") ?? UIImage())
                    .setBottomSheetColor(.cyan)
                    .setBottomSheetCornerRadius(10)
                    .setTitleText("Titulo aqui", color: .brown)
                    .setCaptionText("Subtitulo aqui", color: .systemPink)
                    .setFirstInstructionIcon(UIImage(systemName: "star") ?? UIImage())
                    .setFirstInstructionTitleText("Descrição do ambiente", color: .darkGray)
                    .setSecondInstructionIcon(UIImage(systemName: "house") ?? UIImage())
                    .setSecondInstructionTitleText(
                        "Descrição para uso de accessórios", 
                        color: .magenta
                    )
                    .setContinueButtonText("Iniciar")
                    .setContinueButtonColor(
                        forContent: .lightGray, 
                        background: .systemPink, 
                        border: .white
                    )
            }
            .setCameraPermissionCustomization { cameraPermissionBuilder in
                cameraPermissionBuilder
                    .setCameraPermissionBackgroundColor(.systemPink)
                    .setCameraPermissionBackButtonIcon(UIImage(systemName: "pencil") ?? UIImage())
                    .setCameraPermissionBackButtonColors(
                        forIcon: .white, 
                        background: .black, 
                        border: .blue
                    )
                    .setCameraPermissionImage(UIImage(systemName: "person.fill"), color: .cyan)
                    .setCameraPermissionTitle(
                        withText: "Permissão de câmera customizada", 
                        color: .white
                    )
                    .setCameraPermissionCaption(
                        withText: "Descrição da permissão de câmera", 
                        color: .purple
                    )
                    .setCameraPermissionCheckPermissionButton(withText: "Averiguar")
                    .setCameraPermissionCheckPermissionButtonNormalStateColors(
                        forText: .red, 
                        background: .blue, 
                        border: .white
                    )
                    .setCameraPermissionBottomSheetShape(withColor: .green, cornerRadius: 0)
                    .setCameraPermissionBottomSheetTitle(
                        withText: "Hora de ir para os ajustes", 
                        color: .blue
                    )
                    .setCameraPermissionBottomSheetCaption(
                        withText: "Ou será que não?", 
                        color: .orange
                    )
                    .setCameraPermissionOpenSettingsButton(withText: "Pular para ajustes")
                    .setCameraPermissionOpenSettingsButtonNormalStateColors(
                        forText: .orange, 
                        background: .darkGray, 
                        border: .blue
                    )
                    .setCameraPermissionCloseButton(withText: "Fechar tudo")
                    .setCameraPermissionCloseButtonNormalStateColors(
                        forText: .magenta, 
                        background: .cyan, 
                        border: .red
                    )
            }
            .setLivenessCustomization { livenessBuilder in
                livenessBuilder
                    .setBackgroundColor(.red)
                    .setPromptColors(forText: .green, backgroundColor: .white)
                    .setHeader(withText: "HEADER", textColor: .yellow, backgroundColor: .blue)
                    .setPromptRoundedCorners(enabled: false)
                    .setLAOvalStrokeColors(forCapturing: .cyan, completed: .systemPink)
                    .setGPAOvalStrokeColors(forNotReady: .yellow, completed: .blue)
                    .setFilter(withStyle: .vibrant, color: .purple, backgroundColor: .orange)
            }
            .setLoadingCustomization { loadingBuilder in
                loadingBuilder
                    .setLoadingBackgroundColor(.brown)
                    .setLoadingSpinner(withColor: .red, width: 10.7, scaleFactor: 5)
            }
            .setResultCustomization { resulBuilder in
                resulBuilder
                    .setResultBackgroundColor(.red, forResultType: .success)
                    .setResultImage(nil, forResultType: .success)
                    .setResultMessage("SUCCESS", forResultType: .success)
                    .setResultMessageColor(.blue, forResultType: .success)
                    .setResultBackgroundColor(.blue, forResultType: .error)
                    .setResultImage(nil, forResultType: .error)
                    .setResultMessage("ERROR", forResultType: .error)
                    .setResultMessageColor(.red, forResultType: .error)
            }
            .build()

        let options = LivenessManagerOptions
            .builder(appKey: "APP_KEY", environment: .hml)
            .setIProovCustomization(customization)
            .build()

        let manager = OitiSDKFactory.createLivenessManager(for: .iproov)
        manager.start(at: self, options: options, callback: self)
    }
}

extension ContentViewController: LivenessCallback {
    func onSuccess(_ result: LivenessResult) {
        // Código ...
    }

    func onError(_ error: LivenessError) {
        // Código ...
    }
}
  

📦 Estrutura das Classes Importantes

🧱 Core SDK

ClasseResponsabilidade
OitiSDKFactoryCriar o manager de acordo com o provider fornecido.
LivenessManagerOptionsConfiguração base com AppKey, ambiente, customizações comuns e específicas.
LivenessProviderEnum com os provedores disponíveis.
LivenessManagerGerencia o fluxo de verificação facial usando o provedor fornecido.
LivenessCallbackInterface para retorno de sucesso, erro e cancelamento.

📦 IProov (Provedor Específico)

ClasseResponsabilidade
IProovLivenessCustomizationCustomização da interface visual para o fluxo IProov.
🔧

As estruturas específicas só devem ser utilizadas se o provedor selecionado for o IProov.


🔍 Principais Classes e Métodos de Chamada

Método / ClasseDescrição
OitiSDKFactory.createLivenessManager(for:)Cria um gerenciador do provedor escolhido.
IProovLivenessCustomization.builder()Disponibiliza o builder para customização do fluxo de liveness.
LivenessManager.start(at:options:callback:)Inicia a jornada facial do provedor fornecido.
LivenessCallback.onSuccess(_:)Retorno de sucesso.
OitiResultCallback.onError(_:)Retorno de erro.

📱 Fluxo de Telas

📝 Tela Inicial/Instruções (Pré-Liveness)

Tela que apresenta as instruções iniciais ao usuário antes do início do processo de verificação facial:


📷 Tela de Permissão de Câmera

Exibida quando o usuário ainda não concedeu permissão de acesso à câmera:

🙂 Tela de Liveness

Exibida durante a coleta e análise do liveness:

🔄 Tela de Processamento

Exibida durante o processamento do liveness coletado:

✅ Tela de Resultado

Exibida ao final do processamento do liveness coletado:


🧪 Ambiente de Testes

Durante o desenvolvimento, utilize o ambiente hml com AppKeys fornecidas pela equipe Oiti.

⚠️

Evite o uso do ambiente de produção para testes manuais.


🛠️ Boas Práticas

  • Use o padrão de fábrica para desacoplar a implementação dos provedores.
  • Customize visualmente a interface conforme a identidade do seu app.
  • Trate todos os retornos com UX amigável.
  • Guarde logs e tokens apenas em ambiente seguro.

📜 Changelogs e Versões

VersãoDataDescrição
0.5.002/07/2025Lançamento inicial do SDK
⚠️

Sempre consulte a documentação atualizada para obter os detalhes mais recentes.