DocumentDetector
Documentos suportados
Atualmente, os documentos suportados em iOS são:
Document.RG_FRONT, // frente do RG, parte onde está a foto
Document.RG_BACK, // verso do RG, onde está os dados
Document.RG_FULL, // RG aberta, aparecendo tanto a frente quanto o verso
Document.CNH_FRONT, // frente da CNH, parte onde está a foto
Document.CNH_BACK, // verso da CNH, parte onde está a assinatura
Document.CNH_FULL, // CNH aberta, aparecendo tanto a frente quanto o verso
Document.CRLV, // CRLV
Document.RNE_FRONT, // frente do RNE e RNM, parte onde tem os dados
Document.RNE_BACK, // verso do RNE e RNM, parte onde tem a foto
Document.PASSPORT, // Passaporte
Document.CTPS_FRONT, // Frente da CTPS
Document.CTPS_BACK, // Verso da CTPS
Document.OTHERS, // outros documentos de identificação em geral, como RNE, Identidade Militar, OAB e CRLV
Document.ANY; // permite o envio de qualquer captura
Permissões necessárias
No arquivo info.plist
, adicione as permissões abaixo:
Permissão | Motivo | Obrigatória? |
---|---|---|
Privacy - Camera Usage Description | Para capturar a(s) foto(s) do(s) documento(s) | Não, obrigatória somente no fluxo de captura por câmera |
Privacy - Photo Library Usage Description | Para realizar a abertura da galeria. | Não, obrigatória somente no fluxo de upload |
NSPhotoLibraryUsageDescription
Utilização
Primeiro, instancie um objeto do tipo DocumentDetectorSdk
:
let documentDetector = DocumentDetectorSdk.Builder(mobileToken: "mobileToken")
// veja a tabela abaixo
.build()
DocumentDetectorSdk.Builder
Parâmetro | Obrigatório? |
---|---|
String mobileToken Token de utilização associado à sua conta da CAF | Sim |
.setDocumentDetectorFlow(flow :[DocumentDetectorStep]) Define o fluxo de captura de documentos, como explicado aqui | Sim |
.setPeopleId(peopleId: String?) Identificador do usuário para fins de identificação de perfil fraudador | Não, usado apenas para o analytics |
.setAnalyticsSettings(useAnalytics: Bool) Habilita/desabilita a coleta de dados para o analytics | Não, o padrão é true |
.setPopupSettings(show: Bool) Altera a configuração dos popups inflados antes de cada documento | Não. O padrão é true |
.setDetectionSettings(detectionThreshold : Float) Altera a configuração padrão de detecção do documento, o limiar de confiança do frame (de 0.0 a 1.0, onde 1.0 indica que o SDK só irá aceitar o documento com um frame perfeito) | Não. O padrão é 0.91 |
.setQualitySettings(verifyQuality: Bool, qualityThreshold: Double?) Altera a configuração padrão de verificação de qualidade das capturas, indicando se deseja realizar essa verificação (leva cerca de 2 segundos) podendo ser configurado o limiar de qualidade dessas fotos (valor de 1.0 a 5.0). Além disso, o SDK retornará a URL da imagem na variável DocumentDetectorResult.Capture.ImageUrl . Cuidado, se você decidir por verificar a qualidade nesse parâmetro e ocorrer alguma falha de conexão no envio das imagens, o SDK finalizará com um erro de internet. | Não. O padrão é true e 1.8, respectivamente |
.setLayout(layout: DocumentDetectorLayout) Troca as máscaras do documento de sucesso, falha e normal. Também permite alterar os botões de som e cancelar que ficam no topo da tela. Veja o exemplo. | Não. |
.setColorTheme(color: UIColor) Alterar a cor dos botões de som e cancelar que ficam no topo da tela. Também altera a cor do botão dos popups, inflados antes de cada documento. | Não. |
.enableSound(enableSound: Bool) Habilita/desabilita sons e o ícone de som no SDK | Não. O padrão é true |
.showStepLabel(show: Bool) Mostra/esconde o label inferior central (que contém o nome dos document) | Não. O padrão é true |
.showStatusLabel(show: Bool) Mostra/esconde o label central (que contém o status) | Não. O padrão é true |
.setNetworkSettings(requestTimeout: TimeInterval) Altera as configurações de rede padrão | Não. O padrão é 60 (segundos) |
.setLuminositySensorSettings(message: String?, luminosityThreshold :Float?) Altera as configurações padrão do sensor de luminosidade. O limiar desse sensor é um número que varia do negativo para o positivo. | Não. O padrão é "Ambiente muito escuro" e -3, respectivamente |
.setOrientationSensorSettings(message: String?, orientationThreshold: Double?) Altera as configurações padrão do sensor de orientação. O limiar desse sensor é a aceleração do dispositivo | Não. O padrão é "Celular não está na horizontal" e 0.3, respectivamente |
.setStabilitySensorSettings(message: String?, stabilityThreshold: Double?) Altera as configurações padrão do sensor de estabilidade. O limiar desse sensor é na variação das últimas duas acelerações coletadas do dispositivo. | Não. O padrão é "Mantenha o celular parado" e 0.3, respectivamente |
.setProxySettings(proxySettings: ProxySettings?) Define as configurações de proxy, como explicado aqui | Não. O padrão é nil |
.showPreview(_ show: Bool, title: String?, subtitle: String?, confirmLabel: String?, retryLabel: String?) Habilita/desabilita a pré-visualização de captura. Caso show possua true , após cada captura, o SDK disponibiliza uma tela para o usuário aprovar ou realizar a captura novamente. Nos parâmetros restantes, informe nil para utilização do valor padrão ou uma String para um texto personalizado. | Não. O padrão é false |
.setMessageSettings(waitMessage: String?, fitTheDocumentMessage: String?, verifyingQualityMessage: String?, lowQualityDocumentMessage: String?, uploadingImageMessage: String?) Permite personalizar mensagens exibidas no balão de "status" durante o processo de captura e análise. | Não. O padrão é esse |
.setCompressSettings(compressionQuality: CGFloat) Permite configurar a qualidade no processo de compressão. Por padrão, todas capturas passam por compressão. O método espera como parâmetro valores entre 0 e 1.0, sendo 1.0 a compressão com melhor qualidade (recomendado). | Não. O padrão é 1.0 |
.setGetImageUrlExpireTime(expireTime: Time) Permite personalizar o tempo de expiração da imageUrl . O método recebe como parâmetro o enum Time com os tempos disponíveis. | Não. O padrão é Time.DEFAULT |
.setManualCaptureSettings(enable: Bool, time: TimeInterval) Habilita/desabilita captura manual. O parâmetro time define o tempo para o modo de captura ser habilitado. | Não. O padrão é desabilitado |
.enableMultiLanguage(_ enable: Bool) Habilita/desabilita suporte à multi-idioma. | Não. O padrão é habilitado |
.setGetImageUrlExpireTime(expireTime: String) Define o tempo de duração da URL da imagem no servidor até ser expirada. Espera receber um intervalo de tempo entre "30m" à "30d". Exemplos: setGetImageUrlExpireTime("30m") : Para configurar apenas minutossetGetImageUrlExpireTime("24h") : Para configurar apenas hora(s)setGetImageUrlExpireTime("1h 10m") : Para configurar hora(s) e minuto(s)setGetImageUrlExpireTime("10d") : Para configurar dia(s) | Não. O padrão é 3h |
.setMask(type: MaskType) Define o tipo de máscara utilizada nas capturas. Existem três tipos: .standard , com o padrão pontilhado no formato do documento;.empty , que remove totalmente a máscara. | Não. O padrão é .standard |
.setCurrentStepDoneDelay(currentStepDoneDelay: TimeInterval) Aplica delay na activity após a finalização de cada etapa. Esse método pode ser utilizado para exibir uma mensagem de sucesso na própria tela após a captura, por exemplo. | Não. O padrão é false |
.setUploadSettings(UploadSettings uploadSettings) Define as configurações para o upload de documentos. Ativando esta opção, o fluxo do SDK irá solicitar que o usuário envie os arquivos do documento ao invés de realizar a captura com a câmera do dispositivo. Esta opção também inclui as verificações de qualidade do documento. | Não. Por padrão esta opção está desativada, veja aqui como configurá-la. |
.setResolutionSettings(resolution: Resolution) Permite configurar a resolução de captura. O método espera como parâmetro uma Resolution , que possui as seguintes opções: | Não. O padrão é hd1280x720 |
.setAllowedPassportCountriesList(passportList: [CountryCodes]) Habilita a opção de permitir passaportes de somente um determinado país emissor, ou, uma lista de países. Veja a lista completa em: ISO 3166-1 alpha-3 Ex.: .setAllowedPassportList(passportList: [CountryCodes.BRA]) | Não. Por padrão são aceitos Passaportes emitidos por qualquer país. |
Resolution | Descrição |
---|---|
low | Especifica as configurações de captura adequadas para vídeo de saída e taxas de bits de áudio adequadas para compartilhamento em 3G |
medium | Especifica as configurações de captura adequadas para as taxas de bits de áudio e vídeo de saída adequadas para compartilhamento via WiFi |
high | Especifica as configurações de captura adequadas para saída de áudio e vídeo de alta qualidade |
photo | Especifica as configurações de captura adequadas para saída de qualidade de foto de alta resolução |
inputPriority | Especifica as configurações de captura adequadas para saída de qualidade de foto de alta resolução |
hd1280x720 | Especifica as configurações de captura adequadas para saída de vídeo com qualidade de 720p (1280 x 720 pixels) |
hd1920x1080 | Configurações de captura adequadas para saída de vídeo com qualidade 1080p (1920 x 1080 pixels) |
hd4K3840x2160 | Configurações de captura adequadas para saída de vídeo com qualidade 2160p (3840 x 2160 pixels) |
DocumentDetectorStep
Para criar um fluxo de captura, você precisará criar um array de DocumentDetectorStep
, onde cada elemento será um passo da captura. Para construir cada objeto de DocumentDetectorStep
, você pode informar os seguintes elementos:
Parâmetro | Obrigatório? |
---|---|
document: Document Identifica qual documento você deseja capturar no respectivo passo | Sim |
stepLabel: String? Texto a ser mostrado na parte inferior do layout | Não. Há um padrão por tipo de Document |
illustration: UIImage? Ilustração a ser mostrata no popup anterior à captura | Não. Há um padrão por tipo de Document |
audio: URL? Áudio a ser executado no início do passo Exemplo. | Não. Há um padrão por tipo de Document |
MessageSettings
Atributo | Valor padrão |
---|---|
waitMessage: String Mensagem exibida quando SDK está em processo de abertura | "Aguarde..." |
fitTheDocumentMessage: String Mensagem orientando encaixar o documento na máscara | "Encaixe o documento na marcação" |
verifyingQualityMessage: String Mensagem exibida quando o SDK realiza uma requisição ao backend, verificando qualidade | "Verificando qualidade…" |
lowQualityDocumentMessage: String Mensagem exibida quando a qualidade da captura for reprovada | "Ops, não foi possível ler as informações. Por favor, tente novamente" |
uploadingImageMessage: String Mensagem exibida quando não há verificação de qualidade e a captura está sendo salva nos servidores | "Enviando imagem…" |
popupDocumentSubtitleMessage: String Texto exibido no popup de inicialização de step | "Posicione o documento em uma mesa, centralize-o na marcação e aguarde a captura automática." |
Após a criação do objeto DocumentDetector
, inicie o DocumentDetectorController
passando esse objeto como parâmetro no construtor:
let scannerVC = DocumentDetectorController(documentDetector: documentDetector)
scannerVC.documentDetectorDelegate = self
present(scannerVC, animated: true, completion: nil)
UploadSettings
Para ativar a funcionalidade de upload de documentos é necessário instanciar um objeto do tipo UploadSettings()
e configurar os seus parâmetros:
Parâmetro | Obrigatório? |
---|---|
enable Habilita/desabilita esta funcionalidade. | Não. O padrão é true |
compress Habilita/desabilita a compressão do arquivo antes de realizar o upload. | Não. O padrão é true |
fileFormats Define o(os) formatos de arquivos que serão aceitos para upload. | Não. Por padrão são aceitos: .PDF , .JPEG e .PNG |
maximumFileSize Define o limite máximo em KB do arquivo para upload. | Não. O limite padrão é 20000 KB (20MB). |
Atualmente, os formatos de arquivos suportados são:
public enum FileFormat: String {
case png
case jpeg
case pdf
}
Obtendo o resultado
Para obter o resultado, você deve implementar o delegate DocumentDetectorControllerDelegate
em seu controller:
class YouController: UIViewController, DocumentDetectorControllerDelegate{
// MARK: - Document Detection Delegates
func documentDetectionController(_ scanner: DocumentDetectorController, didFinishWithResults results: DocumentDetectorResult) {
//Called when the process was successfully executed
//The result variable contains the data obtained
}
func documentDetectionControllerDidCancel(_ scanner: DocumentDetectorController) {
// Called when the user cancel
}
func documentDetectionController(_ scanner: DocumentDetectorController, didFailWithError error: DocumentDetectorFailure) {
//Called when the process terminate with an error
//The error variable contains info about error
}
}
DocumentDetectorResult
Parâmetro | Pode ser nulo? |
---|---|
captures:[Capture] O array com as respectivas capturas dos documentos parametrizados | Sim, em caso de erro |
type: String A classe do fluxo de documentos lidos. Esse parâmetro é útil em uma integração com nossa rota de OCR. Os types existentes são: ["blank", "cnh", "cnh_new", "generic", "rg", "rg_new", "rne", "rnm", "ctps", "passport, crlv, crlv_new"] | Sim, em caso de erro |
trackingId: String? Identificador dessa execução em nossos servidores. Se possível, salve este campo e mande-o junto para nossa API. Assim, teremos mais dados de como o usuário se comportou durante a execução | Sim, caso o usuário configure useAnalytics = false ou as chamadas de analytics não funcionem |
Capture
Parâmetro | Pode ser nulo? |
---|---|
image: UIImage Imagem do documento | Não |
imageUrl :String URL do documento no servidor da CAF. Se você quiser essa URL, mantenha habilitado o parâmetro que verifica a qualidade da imagem | Sim, caso você opte por não verificar a qualidade da imagem |
scannedLabel :String Label do respectivo documento dentro das seguintes possibilidades: ["blank", "cnh_back", "cnh_front", "cnh_full", "new_cnh_back", "new_cnh_front", "new_cnh_full", "crlv", "crlv_new", "generic", "rg_back", "rg_front", "rg_full", "rg_new_back", "rg_new_front", "rg_new_full", "rne_back", "rne_front", "rnm_back", "rnm_front", "ctps_back", "ctps_front", "passport"] | Não |
quality :Double Qualidade inferida pelo algoritmo de qualidade do documento, quando habilitado. Varia entre 1.0 e 5.0 | Pode ser 0, caso o SDK não verifique a qualidade |
lensFacing: Int Define a face da câmera que foi utilizada. Utilize DocumentDetectorResult.LENS_FACING_FRONT ou DocumentDetectorResult.LENS_FACING_FRONT para validar. | Não |
DocumentDetectorFailure
Superclasse que leva ao encerramento do SDK. Para saber qual foi o motivo, descubra qual a classe do objeto com o método isKindOfClass()
, equivalente ao instanceof
em Java e ao is
em Dart:
isKindOfClass() | Descrição | Exemplo |
---|---|---|
InvalidTokenReason | O token informado não é válido para o produto correspondente | Parametrizar "test123" como token no builder do SDK |
PermissionReason | Está faltando alguma permissão obrigatória para executar o SDK | Iniciar o DocumentDetector sem a permissão de câmera concedida |
NetworkReason | Falha de conexão com a internet | O usuário ficou sem internet durante o facematch no FaceAuthenticator |
ServerReason | Quando uma requisição do SDK recebe um status code de falha | Em teoria, não deve acontecer. Se acontecer, comunique-nos! |
StorageReason | Não há espaço no armazenamento interno do dispositivo do usuário | Quando não há espaço no armazenamento interno durante a captura da foto do documento |
Exemplos
Customizando o layout
Você pode customizar o layout criando um objeto do tipo DocumentDetectorLayout
e passando por parâmetro no DocumentDetectorBuilder
:
let layout = DocumentDetectorLayout()
layout.changeMaskImages(
greenMask: UIImage(named: "my_green_mask"),
whiteMask: UIImage(named: "my_white_mask"),
redMask: UIImage(named: "my_red_mask"))
layout.changeSoundImages(soundOn: UIImage(named: "my_sound_on_image"),
soundOff: UIImage(named: "my_sound_off_image"))
layout.closeImage = UIImage(named: "my_close_image")
layout.buttonSize = CGFloat(50)
layout.buttonContentMode = .scaleAspectFill
layout.setFont = UIImage(named: "my_font")
let documentDetectorConfiguration = DocumentDetectorBuilder(apiToken: "API_TOKEN")
.setDocumentDetectorFlow(flow: DocumentDetectorBuilder.RG_FLOW)
.setLayout(layout: layout)
.build()
Como obter a URL de um audio
let bundle = Bundle.init(for: type(of: self))
let audioURL = URL(fileURLWithPath: bundle.path(forResource: "my_audio_file", ofType: "mp3")!)