Saltar al contenido principal

React Native

Hay dos formas de integración. Se recomienda el paquete npm.

Paquete npmWebView directo
Configuraciónnpm installManual
Gestión de modalesIntegradaManual
Tipos TypeScriptIncluidosNo

Paquete npm

Instalación

npm install @surtai/faceguard-rn react-native-webview
cd ios && pod install

Requisitos de plataforma

iOS - añade a Info.plist:

Info.plist
<key>NSCameraUsageDescription</key>
<string>FaceGuard necesita acceso a la cámara para la verificación facial</string>

Android - añade a AndroidManifest.xml:

AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA" />

Configuración

FaceGuard.init() y FaceGuard.verify() requieren FaceGuardProvider en la raíz de la app. FaceGuardView no.

App.tsx
import { FaceGuardProvider } from '@surtai/faceguard-rn';

export default function App() {
return (
<FaceGuardProvider>
{/* resto de tu app */}
</FaceGuardProvider>
);
}

Uso

Basado en promesas (requiere provider):

import { FaceGuard } from '@surtai/faceguard-rn';

const result = await FaceGuard.verify({ token: 'PORTAL_TOKEN' });

switch (result.status) {
case 'approved':
console.log('Verificado', result.confidence);
break;
case 'rejected':
console.log('Fallido', result.confidence);
break;
case 'canceled':
console.log('Usuario canceló');
break;
case 'error':
console.log('Error', result.error);
break;
}

Basado en callbacks (requiere provider):

const session = FaceGuard.init({
token: 'PORTAL_TOKEN',
onSuccess: (r) => console.log('aprobado', r.confidence),
onFailed: (r) => console.log('rechazado', r.confidence),
onCancel: () => console.log('cancelado'),
onError: (e) => console.log('error', e.message),
});

// cerrar antes si es necesario
session.destroy();

Componente declarativo (no requiere provider):

import { FaceGuardView } from '@surtai/faceguard-rn';
import { Modal } from 'react-native';

<Modal visible={isOpen} onRequestClose={() => setIsOpen(false)}>
<FaceGuardView
token="PORTAL_TOKEN"
style={{ flex: 1 }}
onSuccess={() => setIsOpen(false)}
onCancel={() => setIsOpen(false)}
/>
</Modal>

Integración con navegación

React Navigation
import { useNavigation } from '@react-navigation/native';
import { FaceGuard } from '@surtai/faceguard-rn';

function VerifyButton({ token }: { token: string }) {
const navigation = useNavigation();

const handleVerify = async () => {
const result = await FaceGuard.verify({ token });

if (result.status === 'approved') {
navigation.replace('Dashboard', { verified: true });
} else if (result.status === 'rejected') {
navigation.replace('VerificationFailed');
} else if (result.status === 'canceled') {
navigation.goBack();
}
};

return <Button title="Verificar" onPress={handleVerify} />;
}

Opciones

OpciónTipoRequeridoPor defectoDescripción
tokenstringJWT del portal desde tu backend
baseUrlstringNohttps://faceguard.surt.comPara entornos que no son producción
langstringNoPredeterminado del dispositivo'en', 'es', 'pt', o 'de'

Callbacks (FaceGuard.init)

CallbackPayloadDescripción
onReadyFaceGuard cargado
onSuccess{ confidence: number }Verificación correcta (0-100)
onFailed{ confidence: number }Verificación fallida (0-100)
onCancelUsuario cerró FaceGuard
onError{ message: string }Algo salió mal

Resultado (FaceGuard.verify)

interface FaceGuardVerifyResult {
status: 'approved' | 'rejected' | 'canceled' | 'error';
confidence?: number; // 0-100, presente para approved/rejected
error?: string; // presente para el estado error
}
Un intento por token

El backend cierra la sesión tras el primer intento. Si el usuario falla, tu backend debe emitir un nuevo token de portal antes de llamar a verify() de nuevo.

WebView directo

Úsalo si quieres control total sobre el ciclo de vida del WebView.

npm install react-native-webview
FaceGuardScreen.tsx
import React from 'react';
import { SafeAreaView, StyleSheet } from 'react-native';
import { WebView } from 'react-native-webview';

interface FaceGuardProps {
token: string;
onApproved: (confidence: number) => void;
onRejected: (confidence: number) => void;
onCanceled: () => void;
onError: (message: string) => void;
}

export function FaceGuardScreen({
token, onApproved, onRejected, onCanceled, onError
}: FaceGuardProps) {
const uri = `https://faceguard.surt.com/intro?token=${encodeURIComponent(token)}`;

const handleMessage = (event: { nativeEvent: { data: string } }) => {
try {
const data = JSON.parse(event.nativeEvent.data);

if (data.action === 'close') {
switch (data.reason) {
case 'approved':
case 'bypass_active':
onApproved(data.confidence ?? 0);
break;
case 'rejected':
onRejected(data.confidence ?? 0);
break;
case 'canceled':
onCanceled();
break;
case 'error':
case 'no_base_photo':
onError(data.error ?? data.reason);
break;
}
}
} catch {
// ignorar mensajes no JSON
}
};

return (
<SafeAreaView style={styles.container}>
<WebView
source={{ uri }}
onMessage={handleMessage}
mediaPlaybackRequiresUserAction={false}
allowsInlineMediaPlayback={true}
mediaCapturePermissionGrantType="grant"
javaScriptEnabled={true}
domStorageEnabled={true}
style={styles.webview}
/>
</SafeAreaView>
);
}

const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: '#0D141A' },
webview: { flex: 1 },
});

iOS - añade a Info.plist:

Info.plist
<key>NSCameraUsageDescription</key>
<string>FaceGuard necesita acceso a la cámara para la verificación facial</string>

Android - añade a AndroidManifest.xml y gestiona la solicitud de permiso:

AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA" />
Permiso de cámara Android
<WebView
{/* ...otras props */}
onPermissionRequest={(request) => {
if (request.resources.includes('android.webkit.resource.VIDEO_CAPTURE')) {
request.grant(request.resources);
}
}}
/>

Idioma

Añade &lang=es (o pt, de) a la URL:

const uri = `https://faceguard.surt.com/intro?token=${token}&lang=es`;
Fondo oscuro

Establece siempre backgroundColor: '#0D141A' en el contenedor para evitar un destello blanco mientras el WebView carga.