Skip to content

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-picker

As 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:

AmbienteURL
Emulador Androidhttp://10.0.2.2:8000
Simulador iOShttp://localhost:8000
Dispositivo físico (LAN)http://192.168.x.x:8000
Produçãohttps://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 takePictureAsync balanceia tamanho vs qualidade
  • Em dispositivos físicos, a API precisa estar acessível na rede local

Valid S.A. - Soluções de Identidade Digital