Integração Mobile
Guia para integrar o SDK de digitais em aplicações React Native / Expo.
Setup
Dependências
bash
npx expo install expo-camera expo-image-pickerAs permissões de câmera são solicitadas automaticamente pelo expo-camera. Para a galeria, o expo-image-picker solicita acesso.
Captura de Imagem
Via Câmera
typescript
import { CameraView, useCameraPermissions } from "expo-camera";
import { useRef } from "react";
function CaptureScreen() {
const cameraRef = useRef<CameraView>(null);
const [permission, requestPermission] = useCameraPermissions();
const capture = async () => {
if (cameraRef.current) {
const photo = await cameraRef.current.takePictureAsync({
quality: 0.9,
base64: false,
});
// photo.uri contém o caminho local da imagem
await processFingerprint(photo.uri);
}
};
return (
<CameraView ref={cameraRef} facing="back" style={{ flex: 1 }}>
{/* Guia estático + botão de captura */}
</CameraView>
);
}Via Galeria
typescript
import * as ImagePicker from "expo-image-picker";
const pickImage = async () => {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
quality: 0.9,
});
if (!result.canceled) {
await processFingerprint(result.assets[0].uri);
}
};Envio para API
typescript
const API_URL = "https://sdk-demo.valid.ia.br";
async function processFingerprint(imageUri: string) {
const formData = new FormData();
formData.append("file", {
uri: imageUri,
type: "image/jpeg",
name: "fingerprint.jpg",
} as any);
const response = await fetch(`${API_URL}/api/process`, {
method: "POST",
body: formData,
headers: {
"Content-Type": "multipart/form-data",
},
});
const result = await response.json();
return result;
}Configuração de URL da API
A URL da API depende do ambiente:
| Ambiente | URL |
|---|---|
| Emulador Android | http://10.0.2.2:8000 |
| Simulador iOS | http://localhost:8000 |
| Dispositivo físico (LAN) | http://192.168.x.x:8000 |
| Produção | https://sdk-demo.valid.ia.br |
typescript
import { Platform } from "react-native";
const API_URL = __DEV__
? Platform.OS === "android"
? "http://10.0.2.2:8000"
: "http://localhost:8000"
: "https://sdk-demo.valid.ia.br";Guia de Posicionamento
No mobile, um guia estático (oval desenhado com Views) é suficiente — não é necessário usar opencv.js.
typescript
import { View, Text, StyleSheet } from "react-native";
function FingerGuide() {
return (
<View style={styles.guideContainer}>
<View style={styles.guideOval} />
<Text style={styles.guideText}>Posicione o dedo dentro do oval</Text>
</View>
);
}
const styles = StyleSheet.create({
guideContainer: {
...StyleSheet.absoluteFillObject,
justifyContent: "center",
alignItems: "center",
},
guideOval: {
width: 180,
height: 280,
borderRadius: 90,
borderWidth: 2,
borderColor: "#00ff88",
borderStyle: "dashed",
},
guideText: {
color: "#fff",
marginTop: 20,
fontSize: 16,
textShadowColor: "#000",
textShadowRadius: 4,
},
});Dicas
- Usar câmera traseira (
facing="back") para melhor qualidade - Resolução 640x480 é suficiente — não precisa de 4K
- Desativar flash para evitar reflexos na pele
- Qualidade 0.8-0.9 no
takePictureAsyncbalanceia tamanho vs qualidade - Em dispositivos físicos, a API precisa estar acessível na rede local