@certiface/sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/README.md +966 -0
- package/RnSdk.podspec +27 -0
- package/android/build.gradle +86 -0
- package/android/gradle.properties +6 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/br/com/oititec/rn/sdk/RnSdkModule.kt +128 -0
- package/android/src/main/java/br/com/oititec/rn/sdk/RnSdkPackage.kt +33 -0
- package/android/src/main/java/br/com/oititec/rn/sdk/executor/LivenessExevutor.kt +66 -0
- package/android/src/main/java/br/com/oititec/rn/sdk/factories/FacetecThemeFactory.kt +233 -0
- package/android/src/main/java/br/com/oititec/rn/sdk/factories/IProovThemeFactory.kt +176 -0
- package/android/src/main/java/br/com/oititec/rn/sdk/managers/AssetManager.kt +152 -0
- package/android/src/main/java/br/com/oititec/rn/sdk/model/Featues.kt +6 -0
- package/android/src/main/java/br/com/oititec/rn/sdk/processors/AssetProcessor.kt +179 -0
- package/android/src/main/java/br/com/oititec/rn/sdk/strategy/FacetecStrategy.kt +25 -0
- package/android/src/main/java/br/com/oititec/rn/sdk/strategy/IProovStrategy.kt +25 -0
- package/android/src/main/java/br/com/oititec/rn/sdk/strategy/LivenessProviderStrategy.kt +16 -0
- package/android/src/main/java/br/com/oititec/rn/sdk/theme/FacetecFonts.kt +85 -0
- package/android/src/main/java/br/com/oititec/rn/sdk/theme/IProovFonts.kt +52 -0
- package/android/src/main/java/br/com/oititec/rn/sdk/utils/AssetProcessor.kt +181 -0
- package/android/src/main/res/drawable/backhand_left.xml +20 -0
- package/android/src/main/res/drawable/backhand_right.xml +20 -0
- package/android/src/main/res/drawable/camera_icon.xml +14 -0
- package/android/src/main/res/drawable/close_icon.xml +11 -0
- package/android/src/main/res/drawable/error_icon.xml +11 -0
- package/android/src/main/res/drawable/neutral_face.xml +11 -0
- package/android/src/main/res/drawable/success_icon.xml +11 -0
- package/android/src/main/res/font/sixty.ttf +0 -0
- package/ios/Extensions/RnSDK+Callbacks.swift +62 -0
- package/ios/Extensions/UIColor+Hex.swift +39 -0
- package/ios/Resources/Media.xcassets/Contents.json +6 -0
- package/ios/Resources/Media.xcassets/shell.imageset/Contents.json +12 -0
- package/ios/Resources/Media.xcassets/shell.imageset/shell.png +0 -0
- package/ios/Resources/Media.xcassets/test.imageset/Contents.json +12 -0
- package/ios/Resources/Media.xcassets/test.imageset/arrow_forward_ios.png +0 -0
- package/ios/RnSdk.h +5 -0
- package/ios/RnSdk.mm +71 -0
- package/ios/RnSdkImpl.swift +91 -0
- package/ios/Utils/RnSdkBundle.swift +27 -0
- package/ios/Utils/ThemeFactory.swift +424 -0
- package/lib/module/@types/result.js +2 -0
- package/lib/module/@types/result.js.map +1 -0
- package/lib/module/@types/theme.js +41 -0
- package/lib/module/@types/theme.js.map +1 -0
- package/lib/module/NativeRnSdk.js +5 -0
- package/lib/module/NativeRnSdk.js.map +1 -0
- package/lib/module/index.js +33 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/utils/AssetProcessor.js +78 -0
- package/lib/module/utils/AssetProcessor.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/@types/result.d.ts +17 -0
- package/lib/typescript/src/@types/result.d.ts.map +1 -0
- package/lib/typescript/src/@types/theme.d.ts +306 -0
- package/lib/typescript/src/@types/theme.d.ts.map +1 -0
- package/lib/typescript/src/NativeRnSdk.d.ts +9 -0
- package/lib/typescript/src/NativeRnSdk.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +14 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/utils/AssetProcessor.d.ts +8 -0
- package/lib/typescript/src/utils/AssetProcessor.d.ts.map +1 -0
- package/package.json +165 -0
- package/src/@types/result.ts +19 -0
- package/src/@types/theme.ts +346 -0
- package/src/NativeRnSdk.ts +18 -0
- package/src/index.tsx +54 -0
- package/src/utils/AssetProcessor.ts +114 -0
package/README.md
ADDED
|
@@ -0,0 +1,966 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="Documentation/images/certiface-header.png" alt="CertiFace" />
|
|
3
|
+
</p>
|
|
4
|
+
<div align="left">
|
|
5
|
+
|
|
6
|
+
# @certiface/sdk
|
|
7
|
+
|
|
8
|
+
SDK React Native para verificação biométrica de liveness (prova de vida), distribuído como `@certiface/sdk`. Integre detecção facial avançada com FaceTec e iProov em aplicações Android e iOS com suporte completo a personalização de temas e interface nativa de alta performance.
|
|
9
|
+
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 📦 Instalação
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @certiface/sdk
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
ou
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
yarn add @certiface/sdk
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## ⚙️ Configuração
|
|
27
|
+
|
|
28
|
+
### Android
|
|
29
|
+
|
|
30
|
+
1. Configure os repositórios necessários no `android/build.gradle`:
|
|
31
|
+
|
|
32
|
+
```gradle
|
|
33
|
+
allprojects {
|
|
34
|
+
repositories {
|
|
35
|
+
google()
|
|
36
|
+
mavenCentral()
|
|
37
|
+
maven {
|
|
38
|
+
url 'https://raw.githubusercontent.com/oititec/android-oiti-sdk-versions/master'
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
2. Adicione as permissões no `android/app/src/main/AndroidManifest.xml`:
|
|
45
|
+
|
|
46
|
+
```xml
|
|
47
|
+
<uses-permission android:name="android.permission.CAMERA" />
|
|
48
|
+
<uses-permission android:name="android.permission.INTERNET" />
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### iOS
|
|
52
|
+
|
|
53
|
+
1. Configure as fontes do CocoaPods no `ios/Podfile`:
|
|
54
|
+
|
|
55
|
+
```ruby
|
|
56
|
+
source 'https://github.com/oititec/ios-artifactory.git'
|
|
57
|
+
source 'https://github.com/CocoaPods/Specs.git'
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
2. Adicione as permissões no `ios/YourApp/Info.plist`:
|
|
61
|
+
|
|
62
|
+
```xml
|
|
63
|
+
<key>NSCameraUsageDescription</key>
|
|
64
|
+
<string>Precisamos acessar sua câmera para verificação de identidade</string>
|
|
65
|
+
<key>NSPhotoLibraryUsageDescription</key>
|
|
66
|
+
<string>Precisamos acessar suas fotos para verificação de identidade</string>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
3. Execute a instalação dos pods:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
cd ios && pod install
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## 🚀 Uso Básico
|
|
76
|
+
|
|
77
|
+
### Importação
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
import {
|
|
81
|
+
CertifaceSDK,
|
|
82
|
+
LivenessProvider,
|
|
83
|
+
Environment,
|
|
84
|
+
type OitiTheme,
|
|
85
|
+
type LivenessResult,
|
|
86
|
+
} from '@certiface/sdk';
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Todas as chamadas à API passam pelo objeto `CertifaceSDK` (por exemplo `CertifaceSDK.startJourney(...)`).
|
|
90
|
+
|
|
91
|
+
### Exemplo Simples
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
import React from 'react';
|
|
95
|
+
import { Button, Alert } from 'react-native';
|
|
96
|
+
import { CertifaceSDK, Environment, LivenessProvider } from '@certiface/sdk';
|
|
97
|
+
|
|
98
|
+
export default function App() {
|
|
99
|
+
const handleVerification = async () => {
|
|
100
|
+
try {
|
|
101
|
+
const appKey = 'your-app-key-here';
|
|
102
|
+
const result = await CertifaceSDK.startJourney(
|
|
103
|
+
appKey,
|
|
104
|
+
Environment.HML,
|
|
105
|
+
LivenessProvider.FACETEC,
|
|
106
|
+
false
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
Alert.alert('Sucesso!', `Verificação concluída: ${result.codID}`);
|
|
110
|
+
} catch (error) {
|
|
111
|
+
Alert.alert('Erro', `Falha: ${error.message}`);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
return <Button title="Iniciar Verificação" onPress={handleVerification} />;
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Resultado Esperado
|
|
120
|
+
|
|
121
|
+
Quando bem-sucedido, `CertifaceSDK.startJourney` retorna um objeto `LivenessResult`:
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
{
|
|
125
|
+
valid: true,
|
|
126
|
+
codID: "abc123def456",
|
|
127
|
+
protocol: "20231105-001"
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## 📚 API
|
|
132
|
+
|
|
133
|
+
### `CertifaceSDK`
|
|
134
|
+
|
|
135
|
+
Objeto com os métodos expostos pelo SDK:
|
|
136
|
+
|
|
137
|
+
| Método | Descrição |
|
|
138
|
+
| ------ | --------- |
|
|
139
|
+
| `CertifaceSDK.startJourney(...)` | Inicia a jornada de liveness |
|
|
140
|
+
| `CertifaceSDK.checkCameraPermission()` | Verifica se a câmera está autorizada |
|
|
141
|
+
| `CertifaceSDK.requestCameraPermission()` | Solicita permissão da câmera |
|
|
142
|
+
|
|
143
|
+
### `CertifaceSDK.startJourney(appKey, environment, provider, isCustomEnabled?, theme?)`
|
|
144
|
+
|
|
145
|
+
Inicia o processo de verificação de liveness.
|
|
146
|
+
|
|
147
|
+
**Parâmetros:**
|
|
148
|
+
|
|
149
|
+
| Nome | Tipo | Obrigatório | Descrição |
|
|
150
|
+
| ----------------- | ------------------ | ----------- | ---------------------------------------------- |
|
|
151
|
+
| `appKey` | `string` | ✅ | Chave de aplicação fornecida pela Oiti |
|
|
152
|
+
| `environment` | `Environment` | ✅ | Ambiente de execução (`HML` ou `PRD`) |
|
|
153
|
+
| `provider` | `LivenessProvider` | ✅ | Provedor de liveness (`FACETEC` ou `IPROOV`) |
|
|
154
|
+
| `isCustomEnabled` | `boolean` | ❌ | Habilita tema personalizado (padrão: `false`) |
|
|
155
|
+
| `theme` | `OitiTheme` | ❌ | Objeto com configurações de tema personalizado |
|
|
156
|
+
|
|
157
|
+
**Retorna:** `Promise<LivenessResult>` com o resultado da verificação
|
|
158
|
+
|
|
159
|
+
**Exemplo:**
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
const result = await CertifaceSDK.startJourney(
|
|
163
|
+
'your-app-key',
|
|
164
|
+
Environment.HML,
|
|
165
|
+
LivenessProvider.FACETEC,
|
|
166
|
+
false
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
const resultWithTheme = await CertifaceSDK.startJourney(
|
|
170
|
+
'your-app-key',
|
|
171
|
+
Environment.PRD,
|
|
172
|
+
LivenessProvider.IPROOV,
|
|
173
|
+
true,
|
|
174
|
+
customTheme
|
|
175
|
+
);
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
### `LivenessResult`
|
|
181
|
+
|
|
182
|
+
Tipo de retorno de `CertifaceSDK.startJourney`:
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
interface LivenessResult {
|
|
186
|
+
valid: boolean;
|
|
187
|
+
codID: string | null;
|
|
188
|
+
protocol: string | null;
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**Propriedades:**
|
|
193
|
+
|
|
194
|
+
| Nome | Tipo | Descrição |
|
|
195
|
+
| ---------- | ---------------- | ---------------------------------------- |
|
|
196
|
+
| `valid` | `boolean` | Indica se a verificação foi bem-sucedida |
|
|
197
|
+
| `codID` | `string \| null` | Código de identificação da verificação |
|
|
198
|
+
| `protocol` | `string \| null` | Protocolo da sessão de verificação |
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
### `CertifaceSDK.checkCameraPermission()`
|
|
203
|
+
|
|
204
|
+
Verifica se a permissão da câmera foi concedida.
|
|
205
|
+
|
|
206
|
+
**Retorna:** `Promise<boolean>`
|
|
207
|
+
|
|
208
|
+
**Exemplo:**
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
const hasPermission = await CertifaceSDK.checkCameraPermission();
|
|
212
|
+
if (!hasPermission) {
|
|
213
|
+
console.log('Permissão não concedida');
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Resultado:**
|
|
218
|
+
|
|
219
|
+
- `true` - Permissão concedida
|
|
220
|
+
- `false` - Permissão negada
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
### `CertifaceSDK.requestCameraPermission()`
|
|
225
|
+
|
|
226
|
+
Solicita permissão da câmera ao usuário.
|
|
227
|
+
|
|
228
|
+
**Retorna:** `Promise<boolean>`
|
|
229
|
+
|
|
230
|
+
**Exemplo:**
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
const granted = await CertifaceSDK.requestCameraPermission();
|
|
234
|
+
if (granted) {
|
|
235
|
+
console.log('Usuário concedeu permissão');
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**Resultado:**
|
|
240
|
+
|
|
241
|
+
- `true` - Usuário concedeu permissão
|
|
242
|
+
- `false` - Usuário negou permissão
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## 🎨 Personalização de Tema
|
|
247
|
+
|
|
248
|
+
O SDK oferece suporte a temas personalizados para os provedores **FaceTec** e **iProov**.
|
|
249
|
+
|
|
250
|
+
### Estrutura do Tema
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
import { CertifaceSDK, LivenessProvider, Environment, type OitiTheme } from '@certiface/sdk';
|
|
254
|
+
|
|
255
|
+
const customTheme: OitiTheme = {
|
|
256
|
+
facetec: {
|
|
257
|
+
colors: {
|
|
258
|
+
frameBackground: '#1A1A1A',
|
|
259
|
+
frameBorder: '#FF6B35',
|
|
260
|
+
ovalStroke: '#FF6B35',
|
|
261
|
+
ovalProgressFirst: '#FF6B35',
|
|
262
|
+
ovalProgressSecond: '#FFD700',
|
|
263
|
+
},
|
|
264
|
+
texts: {
|
|
265
|
+
readyHeader1: 'Prepare-se',
|
|
266
|
+
readyHeader2: 'para verificação',
|
|
267
|
+
readyButton: 'Iniciar',
|
|
268
|
+
},
|
|
269
|
+
fonts: {
|
|
270
|
+
readyScreenHeader: 'CustomFont',
|
|
271
|
+
},
|
|
272
|
+
},
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
await CertifaceSDK.startJourney(
|
|
276
|
+
appKey,
|
|
277
|
+
Environment.HML,
|
|
278
|
+
LivenessProvider.FACETEC,
|
|
279
|
+
true,
|
|
280
|
+
customTheme
|
|
281
|
+
);
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### Opções de Provider
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
enum LivenessProvider {
|
|
288
|
+
FACETEC = 'FACETEC',
|
|
289
|
+
IPROOV = 'IPROOV',
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Opções de Environment
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
enum Environment {
|
|
297
|
+
HML = 'HML',
|
|
298
|
+
PRD = 'PRD',
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## 💡 Exemplos
|
|
303
|
+
|
|
304
|
+
### Exemplo com Gerenciamento de Permissões
|
|
305
|
+
|
|
306
|
+
```typescript
|
|
307
|
+
import React, { useState } from 'react';
|
|
308
|
+
import { View, Button, Alert, ActivityIndicator } from 'react-native';
|
|
309
|
+
import {
|
|
310
|
+
CertifaceSDK,
|
|
311
|
+
Environment,
|
|
312
|
+
LivenessProvider,
|
|
313
|
+
type LivenessResult,
|
|
314
|
+
} from '@certiface/sdk';
|
|
315
|
+
|
|
316
|
+
export default function LivenessScreen() {
|
|
317
|
+
const [loading, setLoading] = useState(false);
|
|
318
|
+
|
|
319
|
+
const handleVerification = async () => {
|
|
320
|
+
setLoading(true);
|
|
321
|
+
|
|
322
|
+
try {
|
|
323
|
+
const hasPermission = await CertifaceSDK.checkCameraPermission();
|
|
324
|
+
|
|
325
|
+
if (!hasPermission) {
|
|
326
|
+
const granted = await CertifaceSDK.requestCameraPermission();
|
|
327
|
+
if (!granted) {
|
|
328
|
+
Alert.alert('Erro', 'Permissão da câmera é necessária');
|
|
329
|
+
setLoading(false);
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
const appKey = 'your-app-key-here';
|
|
335
|
+
const result: LivenessResult = await CertifaceSDK.startJourney(
|
|
336
|
+
appKey,
|
|
337
|
+
Environment.HML,
|
|
338
|
+
LivenessProvider.FACETEC,
|
|
339
|
+
false
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
if (result.valid) {
|
|
343
|
+
Alert.alert(
|
|
344
|
+
'Verificação Aprovada!',
|
|
345
|
+
`Protocolo: ${result.protocol}\nCódigo: ${result.codID}`
|
|
346
|
+
);
|
|
347
|
+
} else {
|
|
348
|
+
Alert.alert('Verificação Recusada');
|
|
349
|
+
}
|
|
350
|
+
} catch (error) {
|
|
351
|
+
Alert.alert('Erro', error.message);
|
|
352
|
+
} finally {
|
|
353
|
+
setLoading(false);
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
return (
|
|
358
|
+
<View style={{ flex: 1, justifyContent: 'center', padding: 20 }}>
|
|
359
|
+
{loading ? (
|
|
360
|
+
<ActivityIndicator size="large" color="#007AFF" />
|
|
361
|
+
) : (
|
|
362
|
+
<Button title="Iniciar Verificação" onPress={handleVerification} />
|
|
363
|
+
)}
|
|
364
|
+
</View>
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
**Resultado de Sucesso:**
|
|
370
|
+
|
|
371
|
+
```typescript
|
|
372
|
+
{
|
|
373
|
+
valid: true,
|
|
374
|
+
codID: "abc123def456",
|
|
375
|
+
protocol: "20231105-001"
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
**Resultado de Erro:**
|
|
380
|
+
|
|
381
|
+
```typescript
|
|
382
|
+
{
|
|
383
|
+
valid: false,
|
|
384
|
+
codID: null,
|
|
385
|
+
protocol: null
|
|
386
|
+
}
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
391
|
+
### Exemplo com Tema Customizado Completo
|
|
392
|
+
|
|
393
|
+
```typescript
|
|
394
|
+
import React from 'react';
|
|
395
|
+
import { Button, Alert } from 'react-native';
|
|
396
|
+
import {
|
|
397
|
+
CertifaceSDK,
|
|
398
|
+
LivenessProvider,
|
|
399
|
+
Environment,
|
|
400
|
+
type OitiTheme,
|
|
401
|
+
type LivenessResult,
|
|
402
|
+
} from '@certiface/sdk';
|
|
403
|
+
|
|
404
|
+
const customTheme: OitiTheme = {
|
|
405
|
+
facetec: {
|
|
406
|
+
colors: {
|
|
407
|
+
frameBackground: '#1A1A1A',
|
|
408
|
+
frameBorder: '#FF6B35',
|
|
409
|
+
ovalStroke: '#FF6B35',
|
|
410
|
+
ovalProgressFirst: '#FF6B35',
|
|
411
|
+
ovalProgressSecond: '#FFD700',
|
|
412
|
+
guidanceButtonBackgroundNormal: '#FF6B35',
|
|
413
|
+
guidanceButtonTextNormal: '#FFFFFF',
|
|
414
|
+
},
|
|
415
|
+
texts: {
|
|
416
|
+
readyHeader1: 'Prepare-se',
|
|
417
|
+
readyHeader2: 'para a verificação',
|
|
418
|
+
readyMessage1: 'Posicione seu rosto',
|
|
419
|
+
readyMessage2: 'dentro do círculo',
|
|
420
|
+
readyButton: 'Começar',
|
|
421
|
+
feedbackCenterFace: 'Centralize seu rosto',
|
|
422
|
+
feedbackHoldSteady: 'Mantenha-se parado',
|
|
423
|
+
},
|
|
424
|
+
},
|
|
425
|
+
instructions: {
|
|
426
|
+
colors: {
|
|
427
|
+
background: '#2E2E2E',
|
|
428
|
+
title: '#FFFFFF',
|
|
429
|
+
continueButtonBackground: '#FF6B35',
|
|
430
|
+
},
|
|
431
|
+
texts: {
|
|
432
|
+
title: 'Verificação de Identidade',
|
|
433
|
+
caption: 'Siga as instruções',
|
|
434
|
+
continueButton: 'Continuar',
|
|
435
|
+
},
|
|
436
|
+
},
|
|
437
|
+
result: {
|
|
438
|
+
colors: {
|
|
439
|
+
successBackground: '#E8F5E8',
|
|
440
|
+
successText: '#2E7D32',
|
|
441
|
+
errorBackground: '#FFEBEE',
|
|
442
|
+
errorText: '#C62828',
|
|
443
|
+
},
|
|
444
|
+
texts: {
|
|
445
|
+
success: 'Verificação concluída com sucesso!',
|
|
446
|
+
error: 'Erro na verificação. Tente novamente.',
|
|
447
|
+
},
|
|
448
|
+
},
|
|
449
|
+
};
|
|
450
|
+
|
|
451
|
+
export default function ThemedVerification() {
|
|
452
|
+
const handleStart = async () => {
|
|
453
|
+
try {
|
|
454
|
+
const appKey = 'your-app-key-here';
|
|
455
|
+
const result: LivenessResult = await CertifaceSDK.startJourney(
|
|
456
|
+
appKey,
|
|
457
|
+
Environment.PRD,
|
|
458
|
+
LivenessProvider.FACETEC,
|
|
459
|
+
true,
|
|
460
|
+
customTheme
|
|
461
|
+
);
|
|
462
|
+
|
|
463
|
+
if (result.valid) {
|
|
464
|
+
Alert.alert('Sucesso!', `Protocolo: ${result.protocol}`);
|
|
465
|
+
}
|
|
466
|
+
} catch (error) {
|
|
467
|
+
Alert.alert('Erro', error.message);
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
return <Button title="Iniciar com Tema Custom" onPress={handleStart} />;
|
|
472
|
+
}
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
---
|
|
476
|
+
|
|
477
|
+
### Exemplo com TypeScript e Tratamento de Erros
|
|
478
|
+
|
|
479
|
+
```typescript
|
|
480
|
+
import React, { useState } from 'react';
|
|
481
|
+
import { View, Text, TouchableOpacity, StyleSheet, Alert } from 'react-native';
|
|
482
|
+
import {
|
|
483
|
+
CertifaceSDK,
|
|
484
|
+
Environment,
|
|
485
|
+
LivenessProvider,
|
|
486
|
+
type LivenessResult,
|
|
487
|
+
} from '@certiface/sdk';
|
|
488
|
+
|
|
489
|
+
export default function VerificationComponent() {
|
|
490
|
+
const [result, setResult] = useState<LivenessResult | null>(null);
|
|
491
|
+
const [loading, setLoading] = useState(false);
|
|
492
|
+
|
|
493
|
+
const handleVerification = async () => {
|
|
494
|
+
setLoading(true);
|
|
495
|
+
setResult(null);
|
|
496
|
+
|
|
497
|
+
try {
|
|
498
|
+
const appKey = process.env.OITI_APP_KEY || 'your-app-key';
|
|
499
|
+
const data: LivenessResult = await CertifaceSDK.startJourney(
|
|
500
|
+
appKey,
|
|
501
|
+
Environment.HML,
|
|
502
|
+
LivenessProvider.FACETEC,
|
|
503
|
+
false
|
|
504
|
+
);
|
|
505
|
+
|
|
506
|
+
setResult(data);
|
|
507
|
+
|
|
508
|
+
if (data.valid) {
|
|
509
|
+
Alert.alert('Sucesso', 'Identidade verificada!');
|
|
510
|
+
} else {
|
|
511
|
+
Alert.alert('Falha', 'Verificação não aprovada');
|
|
512
|
+
}
|
|
513
|
+
} catch (error) {
|
|
514
|
+
Alert.alert('Erro', `Não foi possível completar: ${error.message}`);
|
|
515
|
+
} finally {
|
|
516
|
+
setLoading(false);
|
|
517
|
+
}
|
|
518
|
+
};
|
|
519
|
+
|
|
520
|
+
return (
|
|
521
|
+
<View style={styles.container}>
|
|
522
|
+
<TouchableOpacity
|
|
523
|
+
style={[styles.button, loading && styles.buttonDisabled]}
|
|
524
|
+
onPress={handleVerification}
|
|
525
|
+
disabled={loading}
|
|
526
|
+
>
|
|
527
|
+
<Text style={styles.buttonText}>
|
|
528
|
+
{loading ? 'Verificando...' : 'Iniciar Verificação'}
|
|
529
|
+
</Text>
|
|
530
|
+
</TouchableOpacity>
|
|
531
|
+
|
|
532
|
+
{result && (
|
|
533
|
+
<View style={styles.resultContainer}>
|
|
534
|
+
<Text style={styles.resultTitle}>Resultado:</Text>
|
|
535
|
+
<Text>Status: {result.valid ? 'Aprovado' : 'Reprovado'}</Text>
|
|
536
|
+
{result.protocol && <Text>Protocolo: {result.protocol}</Text>}
|
|
537
|
+
{result.codID && <Text>Código: {result.codID}</Text>}
|
|
538
|
+
</View>
|
|
539
|
+
)}
|
|
540
|
+
</View>
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
const styles = StyleSheet.create({
|
|
545
|
+
container: {
|
|
546
|
+
flex: 1,
|
|
547
|
+
justifyContent: 'center',
|
|
548
|
+
padding: 20,
|
|
549
|
+
},
|
|
550
|
+
button: {
|
|
551
|
+
backgroundColor: '#007AFF',
|
|
552
|
+
padding: 15,
|
|
553
|
+
borderRadius: 8,
|
|
554
|
+
alignItems: 'center',
|
|
555
|
+
},
|
|
556
|
+
buttonDisabled: {
|
|
557
|
+
backgroundColor: '#cccccc',
|
|
558
|
+
},
|
|
559
|
+
buttonText: {
|
|
560
|
+
color: 'white',
|
|
561
|
+
fontSize: 16,
|
|
562
|
+
fontWeight: '600',
|
|
563
|
+
},
|
|
564
|
+
resultContainer: {
|
|
565
|
+
marginTop: 20,
|
|
566
|
+
padding: 15,
|
|
567
|
+
backgroundColor: '#f5f5f5',
|
|
568
|
+
borderRadius: 8,
|
|
569
|
+
},
|
|
570
|
+
resultTitle: {
|
|
571
|
+
fontSize: 18,
|
|
572
|
+
fontWeight: 'bold',
|
|
573
|
+
marginBottom: 10,
|
|
574
|
+
},
|
|
575
|
+
});
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
**Possíveis Resultados:**
|
|
579
|
+
|
|
580
|
+
**Sucesso:**
|
|
581
|
+
|
|
582
|
+
```typescript
|
|
583
|
+
{
|
|
584
|
+
valid: true,
|
|
585
|
+
codID: "abc123def456",
|
|
586
|
+
protocol: "20231105-001"
|
|
587
|
+
}
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
**Falha:**
|
|
591
|
+
|
|
592
|
+
```typescript
|
|
593
|
+
{
|
|
594
|
+
valid: false,
|
|
595
|
+
codID: null,
|
|
596
|
+
protocol: null
|
|
597
|
+
}
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
---
|
|
601
|
+
|
|
602
|
+
## 🎭 Tema Completo
|
|
603
|
+
|
|
604
|
+
### Exemplo de Tema Personalizado Completo
|
|
605
|
+
|
|
606
|
+
```typescript
|
|
607
|
+
const customTheme: OitiTheme = {
|
|
608
|
+
facetec: {
|
|
609
|
+
colors: {
|
|
610
|
+
readyScreenHeader: '#FFFFFF',
|
|
611
|
+
readyScreenSubtext: '#CCCCCC',
|
|
612
|
+
readyScreenOvalFill: '#FF6B35',
|
|
613
|
+
readyScreenTextBackground: '#444444',
|
|
614
|
+
resultScreenForeground: '#FF6B35',
|
|
615
|
+
resultScreenBackground: '#F0F8FF',
|
|
616
|
+
ovalStroke: '#FF6B35',
|
|
617
|
+
ovalProgressFirst: '#FF6B35',
|
|
618
|
+
ovalProgressSecond: '#FFD700',
|
|
619
|
+
overlayBackground: '#80000000',
|
|
620
|
+
frameBorder: '#FF6B35',
|
|
621
|
+
frameBackground: '#1A1A1A',
|
|
622
|
+
feedbackBarBackground: '#FFF8DC',
|
|
623
|
+
feedbackMessage: '#333333',
|
|
624
|
+
guidanceBackground: '#2E2E2E',
|
|
625
|
+
guidanceForeground: '#FFFFFF',
|
|
626
|
+
guidanceButtonTextNormal: '#FFFFFF',
|
|
627
|
+
guidanceButtonTextHighlight: '#FFFFFF',
|
|
628
|
+
guidanceButtonTextDisabled: '#AAAAAA',
|
|
629
|
+
guidanceButtonBackgroundNormal: '#FF6B35',
|
|
630
|
+
guidanceButtonBackgroundHighlight: '#FF6B35',
|
|
631
|
+
guidanceButtonBackgroundDisabled: '#666666',
|
|
632
|
+
guidanceButtonBorder: '#FF6B35',
|
|
633
|
+
},
|
|
634
|
+
texts: {
|
|
635
|
+
readyHeader1: 'Prepare-se',
|
|
636
|
+
readyHeader2: 'para verificação',
|
|
637
|
+
readyMessage1: 'Posicione seu rosto',
|
|
638
|
+
readyMessage2: 'dentro do círculo',
|
|
639
|
+
readyButton: 'Iniciar',
|
|
640
|
+
retryHeader: 'Vamos tentar novamente',
|
|
641
|
+
retrySubheader: 'Ajustes necessários',
|
|
642
|
+
retryButton: 'Tentar Novamente',
|
|
643
|
+
resultSuccessMessage: 'Verificação concluída!',
|
|
644
|
+
feedbackCenterFace: 'Centralize seu rosto',
|
|
645
|
+
feedbackHoldSteady: 'Mantenha-se parado',
|
|
646
|
+
feedbackMovePhoneCloser: 'Aproxime o dispositivo',
|
|
647
|
+
feedbackMovePhoneAway: 'Afaste o dispositivo',
|
|
648
|
+
},
|
|
649
|
+
assets: {
|
|
650
|
+
overlayBrandImage: 'overlayBrandImage',
|
|
651
|
+
cancelButtonIcon: 'cancelButtonIcon',
|
|
652
|
+
resultScreenCustomActivityIndicatorImage:
|
|
653
|
+
'resultScreenCustomActivityIndicatorImage',
|
|
654
|
+
},
|
|
655
|
+
fonts: {
|
|
656
|
+
readyScreenHeader: 'sixty',
|
|
657
|
+
readyScreenSubtext: 'sixty',
|
|
658
|
+
resultScreenMessage: 'sixty',
|
|
659
|
+
retryScreenHeader: 'sixty',
|
|
660
|
+
retryScreenSubtext: 'sixty',
|
|
661
|
+
feedbackMessage: 'sixty',
|
|
662
|
+
guidanceHeader: 'sixty',
|
|
663
|
+
guidanceSubtext: 'sixty',
|
|
664
|
+
guidanceButton: 'sixty',
|
|
665
|
+
},
|
|
666
|
+
},
|
|
667
|
+
iproov: {
|
|
668
|
+
colors: {
|
|
669
|
+
title: '#FFFFFF',
|
|
670
|
+
titleBackground: '#2E2E2E',
|
|
671
|
+
promptText: '#FFFFFF',
|
|
672
|
+
promptBackground: '#1A1A1A',
|
|
673
|
+
background: '#FF6B35',
|
|
674
|
+
ovalReady: '#FF6B35',
|
|
675
|
+
ovalNotReady: '#FF3030',
|
|
676
|
+
ovalCapturing: '#FFFFFF',
|
|
677
|
+
ovalCompleted: '#FF6B35',
|
|
678
|
+
},
|
|
679
|
+
texts: {
|
|
680
|
+
title: 'Verificação Biométrica',
|
|
681
|
+
},
|
|
682
|
+
assets: {
|
|
683
|
+
closeButtonIcon: 'closeButtonIcon',
|
|
684
|
+
logoImage: 'logoImage',
|
|
685
|
+
},
|
|
686
|
+
fonts: {
|
|
687
|
+
instructionsTitleFont: 'sixty',
|
|
688
|
+
instructionsCaptionFont: 'sixty',
|
|
689
|
+
instructionsDocumentTypesInstructionsFont: 'sixty',
|
|
690
|
+
instructionsDocumentTipsInstructionsFont: 'sixty',
|
|
691
|
+
instructionsButtonFont: 'sixty',
|
|
692
|
+
permissionTitleFont: 'sixty',
|
|
693
|
+
permissionCaptionFont: 'sixty',
|
|
694
|
+
permissionButtonFont: 'sixty',
|
|
695
|
+
resultMessageFont: 'sixty',
|
|
696
|
+
resultRetryButtonFont: 'sixty',
|
|
697
|
+
},
|
|
698
|
+
},
|
|
699
|
+
instructions: {
|
|
700
|
+
colors: {
|
|
701
|
+
statusBar: '#2E2E2E',
|
|
702
|
+
background: '#2E2E2E',
|
|
703
|
+
backButtonIcon: '#2E2E2E',
|
|
704
|
+
backButtonBackground: '#2E2E2E',
|
|
705
|
+
backButtonBorder: '#2E2E2E',
|
|
706
|
+
bottomSheet: '#1A1A1A',
|
|
707
|
+
title: '#FFFFFF',
|
|
708
|
+
caption: '#CCCCCC',
|
|
709
|
+
firstInstructionTitle: '#FFFFFF',
|
|
710
|
+
secondInstructionTitle: '#FFFFFF',
|
|
711
|
+
continueButtonText: '#FFFFFF',
|
|
712
|
+
continueButtonBackground: '#FF6B35',
|
|
713
|
+
continueButtonBorder: '#FF6B35',
|
|
714
|
+
},
|
|
715
|
+
texts: {
|
|
716
|
+
title: 'Verificação de Identidade',
|
|
717
|
+
caption: 'Siga as instruções para completar o processo',
|
|
718
|
+
firstInstruction: 'Mantenha o documento bem iluminado',
|
|
719
|
+
secondInstruction: 'Use um documento oficial com foto',
|
|
720
|
+
continueButton: 'Continuar',
|
|
721
|
+
},
|
|
722
|
+
assets: {
|
|
723
|
+
backButtonIcon: 'backButtonIcon',
|
|
724
|
+
contextImage: 'contextImage',
|
|
725
|
+
firstInstructionIcon: 'firstInstructionIcon',
|
|
726
|
+
secondInstructionIcon: 'secondInstructionIcon',
|
|
727
|
+
},
|
|
728
|
+
fonts: {
|
|
729
|
+
title: 'sixty',
|
|
730
|
+
caption: 'sixty',
|
|
731
|
+
firstInstructionTitle: 'sixty',
|
|
732
|
+
secondInstructionTitle: 'sixty',
|
|
733
|
+
continueButton: 'sixty',
|
|
734
|
+
},
|
|
735
|
+
},
|
|
736
|
+
permission: {
|
|
737
|
+
colors: {
|
|
738
|
+
statusBar: '#2E2E2E',
|
|
739
|
+
background: '#2E2E2E',
|
|
740
|
+
backButtonIcon: '#2E2E2E',
|
|
741
|
+
backButtonBackground: '#2E2E2E',
|
|
742
|
+
backButtonBorder: '#2E2E2E',
|
|
743
|
+
cameraImage: '#FFFFFF',
|
|
744
|
+
title: '#FFFFFF',
|
|
745
|
+
caption: '#FFFFFF',
|
|
746
|
+
checkPermissionButtonText: '#FFFFFF',
|
|
747
|
+
checkPermissionButtonBackground: '#FF6B35',
|
|
748
|
+
checkPermissionButtonBorder: '#FF6B35',
|
|
749
|
+
bottomSheet: '#FF6B35',
|
|
750
|
+
bottomSheetTitle: '#FF6B35',
|
|
751
|
+
bottomSheetCaption: '#FF6B35',
|
|
752
|
+
openSettingsButtonText: '#FF6B35',
|
|
753
|
+
openSettingsButtonBackground: '#FF6B35',
|
|
754
|
+
openSettingsButtonBorder: '#FF6B35',
|
|
755
|
+
closeButtonText: '#FF6B35',
|
|
756
|
+
closeButtonBackground: '#FF6B35',
|
|
757
|
+
closeButtonBorder: '#FF6B35',
|
|
758
|
+
},
|
|
759
|
+
texts: {
|
|
760
|
+
title: 'Permissões Necessárias',
|
|
761
|
+
caption: 'Permissões Necessárias',
|
|
762
|
+
checkPermissionButton: 'Permitir Acesso',
|
|
763
|
+
bottomSheetTitle: 'Permitir Acesso',
|
|
764
|
+
bottomSheetCaption: 'Permitir Acesso',
|
|
765
|
+
openSettingsButton: 'Permitir Acesso',
|
|
766
|
+
closeButton: 'Permitir Acesso',
|
|
767
|
+
},
|
|
768
|
+
assets: {
|
|
769
|
+
backButtonIcon: 'backButtonIcon',
|
|
770
|
+
cameraImage: 'cameraImage',
|
|
771
|
+
},
|
|
772
|
+
fonts: {
|
|
773
|
+
title: 'sixty',
|
|
774
|
+
caption: 'sixty',
|
|
775
|
+
checkPermissionButton: 'sixty',
|
|
776
|
+
bottomSheetTitle: 'sixty',
|
|
777
|
+
bottomSheetCaption: 'sixty',
|
|
778
|
+
opentSettingsButton: 'sixty',
|
|
779
|
+
closeButton: 'sixty',
|
|
780
|
+
},
|
|
781
|
+
},
|
|
782
|
+
processing: {
|
|
783
|
+
colors: {
|
|
784
|
+
statusBar: '#1A1A1A',
|
|
785
|
+
background: '#1A1A1A',
|
|
786
|
+
loading: '#FFFFFF',
|
|
787
|
+
},
|
|
788
|
+
},
|
|
789
|
+
result: {
|
|
790
|
+
colors: {
|
|
791
|
+
successStatusBar: '#E8F5E8',
|
|
792
|
+
successBackground: '#E8F5E8',
|
|
793
|
+
successText: '#2E7D32',
|
|
794
|
+
errorStatusBar: '#FFEBEE',
|
|
795
|
+
errorBackground: '#FFEBEE',
|
|
796
|
+
errorText: '#C62828',
|
|
797
|
+
retryBackground: '#C62828',
|
|
798
|
+
retryText: '#FFEBEE',
|
|
799
|
+
retryButtonText: '#FF6B35',
|
|
800
|
+
retryButtonBackground: '#FFFFFF',
|
|
801
|
+
retryButtonBorder: '#FFFFFF',
|
|
802
|
+
},
|
|
803
|
+
texts: {
|
|
804
|
+
success: 'Verificação concluída com sucesso!',
|
|
805
|
+
error: 'Houve um erro na verificação. Tente novamente.',
|
|
806
|
+
retryButton: 'Tentar Novamente',
|
|
807
|
+
},
|
|
808
|
+
assets: {
|
|
809
|
+
successImage: 'successImage',
|
|
810
|
+
errorImage: 'errorImage',
|
|
811
|
+
retryImage: 'retryImage',
|
|
812
|
+
},
|
|
813
|
+
fonts: {
|
|
814
|
+
text: 'sixty',
|
|
815
|
+
retryButton: 'sixty',
|
|
816
|
+
},
|
|
817
|
+
},
|
|
818
|
+
};
|
|
819
|
+
```
|
|
820
|
+
|
|
821
|
+
### Configuração de Assets e Fonts
|
|
822
|
+
|
|
823
|
+
Os assets e fonts referenciados no tema precisam ser cadastrados nativamente em cada plataforma:
|
|
824
|
+
|
|
825
|
+
#### Android - Drawable Resources
|
|
826
|
+
|
|
827
|
+
Os assets devem ser adicionados em `android/app/src/main/res/drawable/`:
|
|
828
|
+
|
|
829
|
+
```
|
|
830
|
+
android/app/src/main/res/
|
|
831
|
+
└── drawable/
|
|
832
|
+
├── shell.png
|
|
833
|
+
└── outros_assets.png
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
Formatos aceitos: `.png`, `.jpg`, `.xml` (vector drawables)
|
|
837
|
+
|
|
838
|
+
#### Android - Fonts
|
|
839
|
+
|
|
840
|
+
As fontes devem ser adicionadas em `android/app/src/main/res/font/`:
|
|
841
|
+
|
|
842
|
+
```
|
|
843
|
+
android/app/src/main/res/
|
|
844
|
+
└── font/
|
|
845
|
+
├── sixty.ttf
|
|
846
|
+
└── outras_fontes.ttf
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
Formatos aceitos: `.ttf`, `.otf`
|
|
850
|
+
|
|
851
|
+
#### iOS - Assets
|
|
852
|
+
|
|
853
|
+
Os assets devem ser adicionados em um Asset Catalog (`.xcassets`):
|
|
854
|
+
|
|
855
|
+
```
|
|
856
|
+
ios/YourApp/
|
|
857
|
+
└── Images.xcassets/
|
|
858
|
+
├── shell.imageset/
|
|
859
|
+
│ ├── Contents.json
|
|
860
|
+
│ ├── shell.png
|
|
861
|
+
│ ├── shell@2x.png
|
|
862
|
+
│ └── shell@3x.png
|
|
863
|
+
└── Contents.json
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
Estrutura do `Contents.json` para cada imageset:
|
|
867
|
+
|
|
868
|
+
```json
|
|
869
|
+
{
|
|
870
|
+
"images": [
|
|
871
|
+
{
|
|
872
|
+
"filename": "shell.png",
|
|
873
|
+
"idiom": "universal",
|
|
874
|
+
"scale": "1x"
|
|
875
|
+
},
|
|
876
|
+
{
|
|
877
|
+
"filename": "shell@2x.png",
|
|
878
|
+
"idiom": "universal",
|
|
879
|
+
"scale": "2x"
|
|
880
|
+
},
|
|
881
|
+
{
|
|
882
|
+
"filename": "shell@3x.png",
|
|
883
|
+
"idiom": "universal",
|
|
884
|
+
"scale": "3x"
|
|
885
|
+
}
|
|
886
|
+
],
|
|
887
|
+
"info": {
|
|
888
|
+
"author": "xcode",
|
|
889
|
+
"version": 1
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
```
|
|
893
|
+
|
|
894
|
+
#### iOS - Fonts
|
|
895
|
+
|
|
896
|
+
As fontes devem ser adicionadas ao projeto e registradas no `Info.plist`:
|
|
897
|
+
|
|
898
|
+
1. Adicione os arquivos de fonte ao projeto:
|
|
899
|
+
|
|
900
|
+
```
|
|
901
|
+
ios/YourApp/
|
|
902
|
+
└── Fonts/
|
|
903
|
+
├── sixty.ttf
|
|
904
|
+
└── outras_fontes.ttf
|
|
905
|
+
```
|
|
906
|
+
|
|
907
|
+
2. Registre no `Info.plist`:
|
|
908
|
+
|
|
909
|
+
```xml
|
|
910
|
+
<key>UIAppFonts</key>
|
|
911
|
+
<array>
|
|
912
|
+
<string>sixty.ttf</string>
|
|
913
|
+
<string>outras_fontes.ttf</string>
|
|
914
|
+
</array>
|
|
915
|
+
```
|
|
916
|
+
|
|
917
|
+
3. Adicione no Xcode: arraste os arquivos `.ttf` para o projeto no Xcode e marque "Copy items if needed" e o target correto.
|
|
918
|
+
|
|
919
|
+
### Referenciando no Tema
|
|
920
|
+
|
|
921
|
+
Use apenas o nome base do asset/font (sem extensão):
|
|
922
|
+
|
|
923
|
+
```typescript
|
|
924
|
+
assets: {
|
|
925
|
+
overlayBrandImage: 'shell',
|
|
926
|
+
},
|
|
927
|
+
fonts: {
|
|
928
|
+
readyScreenHeader: 'sixty',
|
|
929
|
+
}
|
|
930
|
+
```
|
|
931
|
+
|
|
932
|
+
---
|
|
933
|
+
|
|
934
|
+
## ✨ Funcionalidades
|
|
935
|
+
|
|
936
|
+
- ✅ Verificação de liveness com FaceTec e iProov
|
|
937
|
+
- ✅ Gerenciamento automático de permissões
|
|
938
|
+
- ✅ Suporte completo a temas personalizados
|
|
939
|
+
- ✅ Interface TypeScript com tipagem completa
|
|
940
|
+
- ✅ Suporte para Android e iOS
|
|
941
|
+
- ✅ Integração com TurboModules para performance otimizada
|
|
942
|
+
- ✅ API em JavaScript baseada em `CertifaceSDK` e Promises
|
|
943
|
+
- ✅ Compatível com React Native 0.60+
|
|
944
|
+
|
|
945
|
+
## 📋 Requisitos
|
|
946
|
+
|
|
947
|
+
- React Native ≥ 0.79
|
|
948
|
+
- Android API ≥ 26
|
|
949
|
+
- iOS ≥ 12.0
|
|
950
|
+
- TypeScript ≥ 4.0 (recomendado)
|
|
951
|
+
|
|
952
|
+
## 🔗 Links Úteis
|
|
953
|
+
|
|
954
|
+
- [Changelog](https://github.com/oititec/certiface-sdk-rn/releases)
|
|
955
|
+
|
|
956
|
+
## 📄 Licença
|
|
957
|
+
|
|
958
|
+
MIT © [Oiti](https://github.com/oititec)
|
|
959
|
+
|
|
960
|
+
---
|
|
961
|
+
|
|
962
|
+
<div align="center">
|
|
963
|
+
|
|
964
|
+
**Feito com ❤️ pela equipe Oiti**
|
|
965
|
+
|
|
966
|
+
</div>
|