Guia Detalhado de Uso
Plugin Flutter oficial da CertiFace para integrar jornadas de liveness (detecção de vida) nos apps, com os provedores iProov e FaceTec. O pacote expõe permissões de câmera, início do fluxo nativo em tela cheia e customização visual opcional via ThemeBuilder.
Sumário
- Visão Geral
- Requisitos de Compatibilidade
- Instalação
- Configuração
- Provedor de Liveness
5.1. Provedor IProov
5.2. Provedor Facetec - Estrutura das Classes Importantes
- Principais Classes e Métodos de Chamada
- Fluxo de Telas
8.1. Telas CertiFace
8.2. Telas IProov
8.3. Telas Facetec - Ambiente de Testes
- Boas Práticas
- Changelogs e Versões
- Links Externos
- FAQ e objeções frequentes
- Licença e suporte
1. Visão Geral
O Certiface SDK Flutter permite integrar fluxos de verificação facial com liveness em aplicações Flutter, delegando a captura e a lógica biométrica ao SDK nativo (Android e iOS).
O SDK oferece:
-
Verificação de pré-requisitos
Consulta e solicitação de permissão de câmera (checkPermission/askPermission). -
Execução da jornada
startLivenessabre o fluxo nativo em tela cheia com aappKeye o ambiente (HML ou PRD). -
Escolha do motor de liveness
Parâmetroprovidercom valores'IPROOV'ou'FACETEC'. -
Interface integrada ao app
Telas hospedadas pelo SDK nativo (não é um preview de câmera embutido em umWidgetarbitrário). -
Retorno de resultados
Future<Map<String, dynamic>>contendo:statusresultmessage
Falhas no canal Flutter ↔ nativo são retornadas como
PlatformException.
Fora do escopo do plugin:
- Emissão ou gestão de App Key
Segue o fluxo acordado com a CertiFace. - Configuração nativa (Maven, CocoaPods, credenciais)
Utilize os guias oficiais disponíveis em Links externos.
2. Requisitos de Compatibilidade
Antes de integrar, confira:
| Requisito | Detalhe |
|---|---|
| Flutter/ Dart | Flutter >=3.3.0, Dart SDK ^3.5.3 (conforme o pacote publicado). |
| Projeto host | Projeto Flutter com suporte a plugins nativos (Android e/ou iOS). |
| Android | Gradle 8.0+; minSdkVersion 26 (Android 8.0) ou superior; permissão de câmera; acesso à internet; Activity válida quando startLiveness for chamado. |
| iOS | 13.0+; NSCameraUsageDescription; internet. |
| Câmera e rede | O fluxo de liveness depende de câmera frontal (configurável no tema, apenas para o provedor iProov) e conectividade para os serviços Certiface. |
iOS: Janela e rootViewController: a implementação atual obtém o rootViewController a partir da janela principal da aplicação. Em cenários com múltiplas janelas, deep links ou estados incomuns de ciclo de vida, valide o fluxo em dispositivo real. Erros típicos incluem código NO_CONTROLLER quando o controlador não está disponível.
Android: Activity: se não houver Activity anexada ao plugin (por exemplo, contexto errado), o canal pode retornar NO_ACTIVITY.
3. Instalação
Via pub.dev
dependencies:
certiface_sdk: ^1.2.0Via GitHub
dependencies:
certiface_sdk:
git:
url: https://github.com/oititec/certiface-sdk-flutter.git
ref: main # ou a branch / tag desejadaDepois execute flutter pub get.
4. Configuração
- Adicione a dependência
certiface_sdknopubspec.yamldo seu app. - Conclua a configuração nativa (repositórios Maven, CocoaPods, permissões e chaves) seguindo o Guia de Instalação Flutter.
- Obtenha a App Key (e demais credenciais) pelo fluxo acordado com a Certiface (painel, API de credenciais ou integração do seu produto).
- Importe o SDK:
import 'package:certiface_sdk/certiface_sdk.dart';
import 'package:certiface_sdk/common/theme_builder.dart'; // apenas se usar tema customizado- Mantenha uma instância de
CertifaceSdk(por exemplo noStatede um widget ou em um serviço injetável):
final _certifaceSdk = CertifaceSdk();Canal de comunicação: o plugin usa o method channel oiti_sdk entre Dart e o código nativo.
Provedor de Liveness
Não é necessário instanciar um provedor em Dart.
Basta informar o parâmetro provider na chamada de startLiveness.
Provedores disponíveis
| Provedor | Valor (provider) | Observação |
|---|---|---|
| iProov | 'IPROOV' | Jornada com verificação passiva (inclui uso de iluminação/desafio luminoso conforme o SDK iProov). |
| FaceTec | 'FACETEC' | Jornada com verificação ativa (orientação de movimentos / rosto), conforme o SDK FaceTec. |
| Outro valor | — | Comportamento diferente por plataforma — veja o alerta abaixo. |
⚠️ Validação de provider difere entre Android e iOS:
- Android: a comparação é case-insensitive. Qualquer valor diferente de
'IPROOV'/'FACETEC'(em qualquer caixa) faz o canal retornar erroINVALID_ARGUMENTcom a mensagemprovider inválido. - iOS: a comparação é case-sensitive e só reconhece a string exata
'FACETEC'para selecionar o FaceTec. Qualquer outro valor — incluindo erros de digitação, caixa diferente ('facetec') ou mesmo'IPROOV'— não gera erro: o fluxo iProov é iniciado silenciosamente.
Recomenda-se sempre usar as strings exatas 'IPROOV' ou 'FACETEC' (maiúsculas) para evitar esse comportamento divergente.
💡 Dica:
Na API Dart, provider e environment são strings (não há enum público LivenessProvider no pacote). Para legibilidade no app, é possível definir constantes:
const kProviderIproov = 'IPROOV';
const kProviderFacetec = 'FACETEC';Fluxo recomendado antes de startLiveness:
-
Verificar permissão de câmera
UsecheckPermission(). -
Solicitar permissão (se necessário)
UseaskPermission()(abre diálogo nativo). -
Iniciar o fluxo de liveness com uma App Key válida
ChamestartLivenessinformando:environmentprovider- (opcional) tema customizado
-
Tratar o resultado
O retorno éMap<String, dynamic>contendo:statusresultmessage
Falhas no canal Flutter ↔ nativo retornam como
PlatformException.
Boas práticas:
Em widgets, após await, verifique se o widget ainda está montado (por exemplo mounted em StatefulWidget) antes de chamar setState.
Personalização visual:
isCustomEnabled: falseuse o tema padrão do SDK;themedeve sernull.isCustomEnabled: trueconstrua o tema comThemeBuildere passetheme: builder.toJson().
5.1. Provedor: iProov
-
Definição do provider
Passeprovider: 'IPROOV'
(case-insensitive no Android; no iOS, qualquer valor diferente de'FACETEC'já resulta em iProov — veja o alerta na seção anterior) -
Customização do iProov (miolo)
Pode ser ajustada de duas formas:- Via
ThemeBuilderglobal (setFontResource,setFilter,setOrientation,setCamera,setOvalColors, etc. — esses campos só se aplicam ao iProov) - Via
setIproovTheme(...)dentro doThemeBuilder
- Via
-
Demais telas do fluxo (casca Certiface)
As telas de:- instruções
- permissão
- processamento
usam os mesmos blocos de tema (
instructions,permission,processing) compartilhados com a casca do FaceTec. Já a tela de resultado (setResultTheme) é exclusiva do iProov — não é aplicada quandoprovider: 'FACETEC'.
Exemplo mínimo:
final res = await certifaceSdk.startLiveness(
appKey,
environment: 'HML',
provider: 'IPROOV',
isCustomEnabled: false,
theme: null,
);5.2. Provedor: FaceTec
-
Definição do provider
Passeprovider: 'FACETEC'— no iOS, a string deve ser exatamente'FACETEC'(case-sensitive); qualquer outro valor é tratado como iProov (veja o alerta na seção anterior). -
Renderização da experiência
A experiência do FaceTec é totalmente renderizada pelo SDK nativo. -
Customização visual (limitada em relação ao iProov)
OThemeBuildersó alimenta a (casca Certiface) para o FaceTec em:- telas de instruções
- permissão
- processamento
⚠️ A tela de resultado (
setResultTheme) e os campos "globais" doThemeBuilder(setFontResource,setIsEnabledScreenShots,setDisableExteriorEffects,setTimeoutSecs,setPromptRoundedCorners,setFilter,setOrientation,setCamera,setOvalColors) não têm efeito no provedor FaceTec — tanto no Android quanto no iOS, esses campos só são lidos pelo caminho de customização do iProov. As telas específicas do FaceTec (oval, guidance, retry, resultado) usam customização própria do SDK nativo FaceTec, que não é exposta pela API públicaThemeBuilderdeste plugin no momento.
Exemplo mínimo:
final res = await certifaceSdk.startLiveness(
appKey,
environment: 'HML',
provider: 'FACETEC',
isCustomEnabled: false,
theme: null,
);Chamada típica com tema customizado:
final res = await certifaceSdk.startLiveness(
appKey,
environment: 'HML',
provider: 'FACETEC',
isCustomEnabled: useCustomTheme,
theme: useCustomTheme ? myThemeBuilder.toJson() : null,
);6. Estrutura das classes importantes
Visão geral (API pública e canal)
flowchart LR
subgraph dart [Dart]
CertifaceSdk
ThemeBuilder
end
subgraph bridge [Plugin]
CertifaceSdkPlatform
MethodChannelCertifaceSdk
end
CertifaceSdk --> CertifaceSdkPlatform
CertifaceSdkPlatform --> MethodChannelCertifaceSdk
ThemeBuilder -->|toJson no startLiveness| MethodChannelCertifaceSdk
Estrutura do ThemeBuilder:
| Componente | Descrição |
|---|---|
| ThemeBuilder | Opções globais (título, cores, oval, timeout, filtro, orientação, câmera, etc.) |
| InstructionsThemeBuilder | Configurado via setInstructionsTheme |
| PermissionThemeBuilder | Configurado via setPermissionTheme |
| ProcessingThemeBuilder | Configurado via setProcessingTheme |
| ResultThemeBuilder | Configurado via setResultTheme |
| IproovThemeBuilder | Configurado via setIproovTheme |
Arquivos de referência no repositório:
7. Principais Classes e Métodos de Chamada
Classe CertifaceSdk
CertifaceSdk| Método | Descrição |
|---|---|
Future<String?> getPlatformVersion() | Informação opcional da versão nativa; útil para diagnóstico. |
Future<bool> checkPermission() | Indica se o app já tem permissão de câmera; não exibe UI. |
Future<bool> askPermission() | Solicita permissão de câmera ao usuário (fluxo nativo). |
Future<Map<String, dynamic>> startLiveness(...) | Inicia a jornada de liveness em tela cheia nativa. |
Assinatura de startLiveness:
Future<Map<String, dynamic>> startLiveness(
String appKey, {
String environment = 'HML',
String provider = 'IPROOV',
bool isCustomEnabled = false,
Map<String, dynamic>? theme,
});| Parâmetro | Tipo | Descrição |
|---|---|---|
appKey | String | Obrigatório. Chave da aplicação fornecida pela Certiface. |
environment | String | 'HML' (homologação) ou 'PRD' (produção). Outro valor é tratado como HML no iOS; no Android, valores diferentes de PRD tendem a homologação. |
provider | String | 'IPROOV' ou 'FACETEC'. |
isCustomEnabled | bool | Se true, o mapa theme é aplicado na UI nativa; se false, tema padrão (theme pode ser null). |
theme | Map<String, dynamic>? | Normalmente o retorno de ThemeBuilder() encadeado com .toJson() quando isCustomEnabled é true. |
Tratamento do retorno
O plugin devolve um mapa com a leitura usual:
- Se
res['status'] == 'success': sucesso; Detalhes costumam vir emres['result'](mapa com campos conforme contrato do backend / SDK nativo). - Caso contrário: erro de negócio ou de fluxo, com mensagem em
res['message'].
Exemplo:
import 'package:flutter/services.dart';
import 'package:certiface_sdk/certiface_sdk.dart';
Future<void> runLiveness(CertifaceSdk sdk, String appKey) async {
Map<String, dynamic> res = {};
try {
res = await sdk.startLiveness(
appKey,
environment: 'HML',
provider: 'FACETEC',
isCustomEnabled: false,
theme: null,
);
} on PlatformException catch (e) {
// Falha no method channel (argumento inválido, activity indisponível, etc.)
// e.code, e.message
return;
}
if (res['status'] == 'success') {
final inner = res['result'];
// use inner conforme o guia de retornos da Certiface
} else {
final message = res['message'];
// exibir erro ao usuário
}
}Para o significado exato de cada campo em result, consulte o Guia de Tratamento de Retorno.
ThemeBuilder e exemplos com propriedades
ThemeBuilder e exemplos com propriedadesAPI fluente
Cada método set... retorna o próprio builder, permitindo encadeamento:
ThemeBuilder()
.setTitle(...)
.setInstructionsTheme(...)
.toJson();-
Envio para o nativo
O objeto enviado ao SDK nativo é sempre o resultado de toJson() ao final do encadeamento.
Formatos e padrões
- Cores Hex string:
#RRGGBB - Oval: Formato inteiro:
0xAARRGGBB
Configurações adicionais
Os valores de: setFilter, setOrientation, setCamera e nomes de fontes/assets devem seguir o guia de customização Flutter e os recursos nativos do app.
Tema global (ThemeBuilder)
ThemeBuilder)⚠️ Estas propriedades globais só têm efeito quando provider: 'IPROOV'. No FaceTec elas são ignoradas pelo código nativo (Android e iOS) — veja a seção 5.2 Provedor: FaceTec.
| Propriedade | Tipo | Uso |
|---|---|---|
setTitle | String | Título da jornada |
setTitleColor | String (hex) | Cor do título ('#RRGGBB') |
setHeaderBackgroundColor | String (hex) | Fundo do cabeçalho |
setPromptTextColorsetPromptBackgroundColor | String (hex) | Texto e fundo do prompt |
setSurroundColor | String (hex) | Cor ao redor da área de captura |
setFontResource | int | Fonte nativa |
setIsEnabledScreenShots | bool | Permite capturas de tela |
setDisableExteriorEffects | bool | Desativa efeitos exteriores |
setTimeoutSecs | int | Timeout da sessão (segundos) |
setPromptRoundedCorners | bool | Cantos arredondados do prompt |
setFilter(type, style) | String | Ex: 'Natural', 'CLEAR' |
setOrientation(gpa, la) | String | Ex: 'PORTRAIT' |
setCamera | String | Ex: 'FRONT' |
setOvalColors(...) | int (ARGB) | Cores do oval (0xAARRGGBB) |
Instruções (setInstructionsTheme → InstructionsThemeBuilder)
setInstructionsTheme → InstructionsThemeBuilder)| Área | Setters (exemplos) |
|---|---|
| Cores | setStatusBarColor,setBackgroundColor,setBackButtonIconColor,setBackButtonBackgroundColor,setBackButtonBorderColor,setBottomSheetColor,setTitleColor,setCaptionColor,setFirstInstructionTitleColor,setSecondInstructionTitleColor,setContinueButtonTextColor,setContinueButtonBackgroundColor,setContinueButtonBorderColor,setContinueButtonColor,setBottomSheetCornerRadius |
| Textos | setTitleText,setCaptionText,setFirstInstructionText,setSecondInstructionText,setContinueButtonText,setDocumentTipsInstructionText,setDocumentTypesInstructionText |
| Fontes | setTitleFont,setCaptionFont,setFirstInstructionTitleFont,setSecondInstructionTitleFont,setContinueButtonFont |
| Assets | setBackButtonIconAsset,setContextImageAsset,setFirstInstructionIconAsset,setSecondInstructionIconAsset(nomes de recurso nativos) |
| Configuração | setShowInstructionScreen,setStatusBarIsDarkIcons |
Permissão (setPermissionTheme → PermissionThemeBuilder)
setPermissionTheme → PermissionThemeBuilder)| Área | Setters (exemplos) |
|---|---|
| Cores | setStatusBarColor,setBackgroundColor,setTitleColor,setCaptionColor,setCheckPermissionButtonTextColor,setCheckPermissionButtonBackgroundColor,setCheckPermissionButtonBorderColor,setCheckPermissionButtonStyle,setBackButtonIconColor,setCameraImageColor |
| Textos | setTitle,setCaptionText,setCheckPermissionButtonText |
| Fontes | setTitleFont,setCaptionFont,setCheckPermissionButtonFont |
| Assets | setBackButtonIconAsset,setCameraImageAsset |
| Outros | setStatusBarIsDarkIcons |
Processamento (setProcessingTheme → ProcessingThemeBuilder)
setProcessingTheme → ProcessingThemeBuilder)| Setter | Descrição |
|---|---|
setStatusBarColor | Cor da status bar. |
setBackgroundColor | Fundo da tela de processamento. |
setLoadingColorsetLoadingDialogColor | Cor do indicador/diálogo de loading. |
setLoadingIndicatorSize | Tamanho do indicador (int). |
setLoadingIndicatorWidth | Espessura do indicador (int). |
setStatusBarIsDarkIcons | Ícones escuros na status bar. |
Resultado (setResultTheme → ResultThemeBuilder)
setResultTheme → ResultThemeBuilder)| Área | Setters (exemplos) |
|---|---|
| Sucesso | setSuccessBackgroundColor,setSuccessTextColor,setSuccessText,setSuccessIcon,setSuccessStatusBarColor,setStatusBarSuccessColor,setStatusBarSuccessIsDarkIcons |
| Erro | setErrorBackgroundColor,setErrorTextColor,setErrorText,setErrorIcon,setErrorStatusBarColor,setStatusBarErrorColor,setStatusBarErrorIsDarkIcons |
| Retry | setRetryButtonColor,setRetryButtonTextColor,setRetryButtonText,setRetryIcon,setRetryButtonFont |
| Geral | setTextFont |
iProov (setIproovTheme → IproovThemeBuilder)
setIproovTheme → IproovThemeBuilder)Ajustes específicos do fluxo iProov (além dos campos globais do ThemeBuilder que também entram no payload iproov via toJson()).
| Área | Setters |
|---|---|
| Cores | setTitleColor,setHeaderBackgroundColor,setPromptTextColor,setPromptBackgroundColor,setSurroundColor |
| Textos | setTitleText |
| Fontes | setInstructionsTitleFont,setInstructionsCaptionFont,setResultMessageFont,setResultRetryButtonFont |
| Assets | setCloseButtonIconAsset,setLogoImageAsset |
Exemplo mínimo
import 'package:certiface_sdk/common/theme_builder.dart';
ThemeBuilder buildThemeMinimal({required bool showInstructionScreen}) {
return ThemeBuilder()
.setTitle('Verificação facial')
.setHeaderBackgroundColor('#1A1A1A')
.setOvalColors(
ready: 0xFF00FF88,
notReady: 0xFFFF4444,
stroke: 0xFFFFFFFF,
completed: 0xFF00FF88,
)
.setInstructionsTheme((b) => b
.setTitleText('Instruções')
.setShowInstructionScreen(showInstructionScreen)
.setContinueButtonText('Iniciar'))
.setPermissionTheme((b) => b.setTitle('Permissões necessárias'));
}
await certifaceSdk.startLiveness(
appKey,
isCustomEnabled: true,
theme: buildThemeMinimal(showInstructionScreen: true).toJson(),
);Exemplo estendido (todas as áreas + iProov)
Use como referência e remova o que não precisar. Substitua os nomes de fonte ('sixty') e de assets ('shell', 'back_icon', etc.) pelos recursos que existem no seu Android / iOS.
import 'package:certiface_sdk/common/theme_builder.dart';
ThemeBuilder buildFullTheme({required bool showInstructionScreen}) {
return ThemeBuilder()
// --- Global ---
.setTitle('Verificação facial')
.setTitleColor('#FFFFFF')
.setHeaderBackgroundColor('#1A1A1A')
.setPromptTextColor('#FFFFFF')
.setPromptBackgroundColor('#2A2A2A')
.setSurroundColor('#00FF88')
.setFontResource(0)
.setIsEnabledScreenShots(true)
.setDisableExteriorEffects(true)
.setTimeoutSecs(90)
.setPromptRoundedCorners(true)
.setFilter('Natural', 'CLEAR')
.setOrientation(gpa: 'PORTRAIT', la: 'PORTRAIT')
.setCamera('FRONT')
.setOvalColors(
ready: 0xFF00FF88,
notReady: 0xFFFF4444,
stroke: 0xFFFFFFFF,
completed: 0xFF00FF88,
)
// --- Instruções ---
.setInstructionsTheme((b) => b
.setTitleText('Instruções')
.setTitleColor('#FFFFFF')
.setCaptionText('Siga as instruções na tela.')
.setCaptionColor('#CCCCCC')
.setBackgroundColor('#2A2A2A')
.setBottomSheetColor('#3A3A3A')
.setDocumentTipsInstructionText('Dicas de documento')
.setDocumentTypesInstructionText('Tipos aceitos')
.setBottomSheetCornerRadius(20.0)
.setContinueButtonText('Iniciar verificação')
.setContinueButtonColor('#00FF88')
.setContinueButtonTextColor('#000000')
.setShowInstructionScreen(showInstructionScreen)
.setStatusBarColor('#1A1A1A')
.setStatusBarIsDarkIcons(false)
.setTitleFont('sixty')
.setCaptionFont('sixty')
.setFirstInstructionTitleFont('sixty')
.setSecondInstructionTitleFont('sixty')
.setContinueButtonFont('sixty')
.setBackButtonIconAsset('shell')
.setContextImageAsset('shell')
.setFirstInstructionIconAsset('shell')
.setSecondInstructionIconAsset('shell'))
// --- Permissão ---
.setPermissionTheme((b) => b
.setTitle('Permissões necessárias')
.setTitleColor('#FFFFFF')
.setBackgroundColor('#2A2A2A')
.setCheckPermissionButtonText('Permitir câmera')
.setCheckPermissionButtonStyle('#00FF88')
.setStatusBarColor('#2A2A2A')
.setStatusBarIsDarkIcons(false)
.setTitleFont('sixty')
.setCaptionFont('sixty')
.setCheckPermissionButtonFont('sixty')
.setBackButtonIconAsset('back_icon')
.setCameraImageAsset('camera_icon'))
// --- Processamento ---
.setProcessingTheme((b) => b
.setBackgroundColor('#000000')
.setLoadingDialogColor('#FFFFFF')
.setLoadingIndicatorSize(120)
.setLoadingIndicatorWidth(12)
.setStatusBarColor('#000000')
.setStatusBarIsDarkIcons(true))
// --- Resultado ---
.setResultTheme((b) => b
.setSuccessBackgroundColor('#E8F5E8')
.setSuccessIcon('success_icon')
.setSuccessText('Verificação concluída.')
.setSuccessTextColor('#2E7D32')
.setErrorBackgroundColor('#FFEBEE')
.setErrorIcon('error_icon')
.setErrorText('Falha na verificação. Tente novamente.')
.setErrorTextColor('#C62828')
.setRetryButtonColor('#00FF88')
.setRetryButtonText('Tentar novamente')
.setRetryButtonTextColor('#000000')
.setStatusBarSuccessColor('#E8F5E8')
.setStatusBarErrorColor('#FFEBEE')
.setStatusBarSuccessIsDarkIcons(true)
.setStatusBarErrorIsDarkIcons(true)
.setTextFont('sixty')
.setRetryButtonFont('sixty'))
// --- Específico iProov ---
.setIproovTheme((b) => b
.setTitleText('Verificação facial')
.setTitleColor('#FFFFFF')
.setHeaderBackgroundColor('#1A1A1A')
.setPromptTextColor('#FFFFFF')
.setPromptBackgroundColor('#2A2A2A')
.setSurroundColor('#00FF88')
.setInstructionsTitleFont('sixty')
.setInstructionsCaptionFont('sixty')
.setResultMessageFont('sixty')
.setResultRetryButtonFont('sixty')
.setLogoImageAsset('logo')
.setCloseButtonIconAsset('close_icon'));
}
// Uso com FaceTec ou iProov:
await certifaceSdk.startLiveness(
appKey,
environment: 'HML',
provider: 'FACETEC', // ou 'IPROOV'
isCustomEnabled: true,
theme: buildFullTheme(showInstructionScreen: true).toJson(),
);Assets referenciados nos setters (ícones, logos, imagens de contexto) precisam existir no projeto Android / iOS com os mesmos nomes de recurso configurados no DevCenter, conforme o guia de customização.
8. Fluxo de telas
A ordem exata e os nomes internos das telas podem variar com a versão do SDK nativo Certiface/iProov/FaceTec. Use esta visão como modelo mental e valide com os guias oficiais e com testes em dispositivo.
8.1. Telas Certiface (camada Oiti)
Camadas de experiência comuns à jornada, configuráveis pelo ThemeBuilder quando isCustomEnabled é true:
| Etapa | Builder / tema | Conteúdo típico |
|---|---|---|
| Instruções | setInstructionsTheme | Textos, cores, fontes, assets; setShowInstructionScreen para exibir ou pular a tela de instruções. Aplica-se a iProov e FaceTec. |
| Permissão | setPermissionTheme | Orientação ao usuário antes de conceder câmera. Aplica-se a iProov e FaceTec. |
| Processamento | setProcessingTheme | Indicadores de carregamento/aguardando processamento. Aplica-se a iProov e FaceTec. |
| Resultado | setResultTheme | Telas de sucesso, erro e opção de nova tentativa. ⚠️ Aplica-se apenas ao iProov — no FaceTec, a tela de resultado usa o comportamento padrão do SDK nativo e não é customizável por este builder. |
8.2. Telas iProov
Após a casca Certiface (quando presente), o usuário entra no fluxo nativo iProov (captura e validação conforme o provedor). Customizações específicas costumam passar por setIproovTheme. Detalhes finos de UI e desafios estão no SDK iProov e na documentação Certiface.
8.3. Telas FaceTec
Após a casca Certiface (quando presente), o usuário percorre o fluxo nativo FaceTec (orientações de pose/movimento, feedback visual, etc.). Diferente do iProov, essas telas nativas do FaceTec (oval, guidance, retry, resultado) não são alimentadas pelo ThemeBuilder público deste plugin — apenas a casca Certiface (instruções, permissão, processamento) é customizável para o FaceTec. Consulte o DevCenter para limites e chaves específicas FaceTec.
9. Ambiente de Testes
Durante o desenvolvimento, utilize o ambiente HML com App Keys fornecidas pela equipe CertiFace.
⚠️ Evite o ambiente de produção (PRD) para testes manuais e massivos: use homologação até o go-live validado.
await sdk.startLiveness(appKey, environment: 'HML', provider: 'FACETEC');10. Boas Práticas
| Tema | Recomendação |
|---|---|
| Ciclo de vida | Após await, verifique mounted antes de chamar setState. |
| Segurança | Não commite App Keys em repositórios públicos. Use variáveis de ambiente ou backend seguro. |
| Erros | Trate PlatformException (canal) e o retorno (status / message) para cobrir falhas nativas e de negócio. |
| Android | Garanta que o app tenha uma Activity válida ao iniciar o liveness. |
| iOS | Teste no fluxo real de abertura do app até a chamada do SDK. |
| Assets | Certifique-se de que os recursos do tema existem nos projetos nativos. |
| Cobertura | Teste separadamente com iProov e FaceTec (pilhas nativas distintas). |
Integração sugerida (serviço)
import 'package:flutter/services.dart';
import 'package:certiface_sdk/certiface_sdk.dart';
class LivenessService {
LivenessService() : _sdk = CertifaceSdk();
final CertifaceSdk _sdk;
Future<bool> ensureCameraPermission() async {
if (await _sdk.checkPermission()) return true;
return _sdk.askPermission();
}
Future<Map<String, dynamic>> run({
required String appKey,
String environment = 'HML',
String provider = 'FACETEC',
bool customUi = false,
Map<String, dynamic>? theme,
}) async {
if (appKey.trim().isEmpty) {
throw StateError('App Key is required');
}
try {
return await _sdk.startLiveness(
appKey.trim(),
environment: environment,
provider: provider,
isCustomEnabled: customUi,
theme: customUi ? theme : null,
);
} on PlatformException catch (e) {
rethrow; // ou mapear para seu modelo de erro
}
}
}11.Changelogs e Versões
Sempre consulte a documentação atualizada e a página do pacote no pub.dev para obter os detalhes mais recentes.
12. Links Externos
- Guia de Instalação Flutter
- Guia de Uso e Integração
- Guia de Tratamento de Retornos
- Customização Flutter
- Portal de Atendimento Oiti
- Compatibilidade dos serviços
- Repositório GitHub
- Rastreador de issues
13. FAQ e objeções frequentes
-
Existe enum
LivenessProviderno Dart?Não na API pública atual. Use as strings
'IPROOV'e'FACETEC'(ou constantes que você definir no app). -
Posso embutir a câmera de liveness dentro de um
ContainerFlutter?Não. O fluxo é apresentado pelo SDK nativo em tela cheia; o Flutter apenas dispara e recebe o resultado.
-
O que vem dentro de
res['result']?Depende do contrato da versão do SDK / backend. Use o Guia de Tratamento de Retornos.
-
Erro
INVALID_ARGUMENTEm geral
appKeyausente ouprovidernão suportado — mas essa validação deprovidersó existe no Android. No iOS, umproviderinválido não gera erro: o fluxo assume iProov silenciosamente. Sempre use as strings exatas'IPROOV'ou'FACETEC'. -
Erro
NO_ACTIVITY(Android)Nenhuma Activity disponível para o plugin no momento da chamada.
-
Erro
NO_CONTROLLER(iOS)Não foi possível obter o
rootViewControllerda janela principal. -
Tema não aplicou/ícone quebrou
Confira
isCustomEnabled: true,themenão nulo e assets nativos com os nomes esperados. Lembre-se também quesetResultThemee os campos "globais" doThemeBuilder(cores, oval, filtro, orientação, câmera, timeout etc.) só se aplicam ao provedor iProov — no FaceTec eles não têm efeito. -
O plugin substitui a configuração Maven/Pods?
Não. A configuração do host continua obrigatória pelos guias de instalação.
-
A customização visual funciona igual para iProov e FaceTec?
Não. Para ambos, a casca Certiface (instruções, permissão, processamento) é customizável. Mas a tela de resultado e os campos globais do
ThemeBuildersó afetam o iProov; as telas nativas específicas do FaceTec (oval, guidance, retry, resultado) não são expostas pela API Dart atual.
14. Licença e suporte
MIT License — veja o arquivo LICENSE.
Para suporte comercial e técnico, utilize os canais da CertiFace indicados no Portal de Atendimento.
