Flutter
Nuestro SDK nativo de Workflows para Flutter permite una experiencia rápida y fluida para tus usuarios, aprovechando las capacidades nativas de los dispositivos sin requerir un navegador web para funcionar. Distribuido de forma privada a través de OnePub, este SDK se instala como un plugin de Flutter y te permite ejecutar workflows, obtener información detallada del proceso y recibir eventos en tiempo real durante su ejecución.
Nota: Esta documentación se actualiza para utilizar únicamente el componente WorkflowsRenderer. La versión anterior basada en WorkflowsController era preliminar y ya no se utiliza.
Requisitos
Para poder utilizar nuestro SDK de Flutter, debes cumplir con los siguientes requisitos:
- Tener una cuenta en OnePub, ya que el SDK se distribuye en un host privado.
- Contar con un Workflow creado a través de nuestra API de Workflows.
- Tener instalado el SDK de Flutter (versión mínima
>=3.3.0) y Dart (versión>=3.0.0 <4.0.0). - Tener instalado el CLI de OnePub en tu máquina.
Instalación
Configuración del CLI de OnePub
Para instalar nuestro SDK de Flutter, primero debes activar el CLI de OnePub. Ejecuta los siguientes comandos en la terminal:
flutter pub global activate onepub
onepub login
Nota: Se requiere un correo electrónico para recibir la invitación y tener acceso al paquete de workflows. Deberás iniciar sesión con tu cuenta de OnePub para poder instalar y actualizar el SDK.
Agregar la dependencia en tu proyecto
Dentro del archivo pubspec.yaml de tu proyecto Flutter, agrega la dependencia del SDK:
dependencies:
workflows_flutter:
hosted: https://onepub.dev/api/jvaxpsdavu
version: ^1.17.0
Uso del SDK
Una vez instalado el SDK, impórtalo en tu proyecto:
import 'package:workflows_flutter/workflows_flutter.dart';
Verificación de Licencia
Antes de iniciar un workflow, debes verificar la licencia del SDK:
verifyWorkflowsLicense(cert: "tu_certificado", passphrase: "tu_passphrase");
Las credenciales de licencia (cert y passphrase) serán compartidas de forma privada por tu administrador de cuenta.
Inicialización y Ejecución de un Workflow
Utiliza el widget WorkflowsRenderer para inicializar y ejecutar un workflow. Este widget se encarga de lanzar el proceso, gestionar la interfaz y notificarte sobre los eventos que se producen durante la ejecución.
return WorkflowsRenderer(
baseUrl: "https://api.rem.tools", // O la URL correspondiente a producción o testing
remApiKey: "YOUR_API_KEY", // Tu API Key proporcionado de forma privada
workflowId: "YOUR_WORKFLOW_ID", // El ID del workflow creado previamente
workflowCustomization: WorkflowCustomization(
theme: WorkflowTheme(
primaryColor: "#468499",
secondaryColor: "#994684",
buttonPrimaryColor: "#468499",
buttonSecondaryColor: "#994684",
buttonTextPrimaryColor: "#FFFFFF",
buttonTextSecondaryColor: "#849946",
backgroundColor: "#c5f2cd",
facetecOverlayColor: "#ffd700",
showHeaderLogo: true,
),
textLocalization: TextLocalization(
localization: (Platform.isAndroid) ? "localizable.xml" : "Localizable.strings",
),
textFont: TextFont(
headerFont: (Platform.isAndroid) ? "montserrat_black.ttf" : "Montserrat-Black.ttf",
bodyFont: (Platform.isAndroid) ? "montserrat_regular.ttf" : "Montserrat-Regular.ttf",
buttonFont: (Platform.isAndroid) ? "playwrite_ar_regular.ttf" : "PlaywriteAR-Regular.ttf",
),
images: Images(
logo: "logo.png",
cameraPermissions: "camara.png",
uploadFaceScan: "facetec_upload.png",
uploadFaceSuccess: "facetec_success.png",
uploadFaceError: "facetec_error.png",
photoMathId: "photo_match_id_image.png",
cameraActiveTorch: "facetec_active.png",
cameraInactiveTorch: "facetec_inactive.png",
fingerPrint: "facetec_active.png",
successPage: "success_image.svg",
errorPage: "error_image.svg",
unavailablePage: "unavailable_image.svg",
locationPage: "location_image.svg",
biometricSignPage: "enroll_fingerprint_image.svg",
enrollFingerprintPage: "enroll_fingerprint_image.svg",
enrollBasicPage: "id_scan_image.svg",
enrollFullPage: "id_scan_image.svg",
authPage: "id_scan_image.svg",
livenessPage: "id_scan_image.svg",
faceEnrollment3dPage: "id_scan_image.svg",
),
),
onStart: (workflowResult) {
print("onStart ${workflowResult.success}");
print("onStart ${workflowResult.error}");
},
onStepEvent: (step) {
print("onStepEvent ${step.status}");
},
onWorkflowEvent: (workflow) {
print("onWorkflowEvent ${workflow.status}");
},
);
Importante: Asegúrate de completar correctamente los parámetros (
baseUrl,remApiKey,workflowId, etc.) según los datos de tu proyecto.
Configuración Específica para Android
Requisitos de SDK de Android
- API mínima: 24
- API máxima: 36
- API de compilación y destino: 36
Configuración del build.gradle (app)
Dentro del archivo android/app/build.gradle, realiza los siguientes ajustes:
1. Agregar repositorio Maven
Versión build.gradle (Groovy):
android {
// ...
repositories {
maven {
url "https://us-central1-maven.pkg.dev/gendra-services/workflows-mobile"
credentials {
username = "_json_key"
password = file("tu_archivo_credenciales.json").text
}
}
}
}
Versión build.gradle.kts (Kotlin DSL):
android {
// ...
repositories {
maven {
url = uri("https://us-central1-maven.pkg.dev/gendra-services/workflows-mobile")
credentials {
username = "_json_key"
password = file("tu_archivo_credenciales.json").readText()
}
}
}
}
El archivo de service account (JSON) es proporcionado por REM. Contacta a tu administrador de cuenta para obtenerlo.
2. Configurar versiones del SDK
android {
compileSdkVersion 36
defaultConfig {
minSdkVersion 24
targetSdkVersion 36
}
// ...
}
3. Configuración de Release Build
Versión build.gradle (Groovy):
android {
// ...
buildTypes {
release {
shrinkResources false
}
}
aaptOptions {
noCompress "tflite", "task"
}
sourceSets {
main {
assets.srcDirs += 'src/main/assets'
}
}
}
Versión build.gradle.kts (Kotlin DSL):
android {
// ...
buildTypes {
release {
isShrinkResources = false
}
}
androidResources {
noCompress += listOf("tflite", "task")
}
sourceSets {
getByName("main") {
assets.srcDirs("src/main/assets")
}
}
}
Reglas para ProGuard
Agrega las siguientes reglas en el archivo proguard-rules.pro:
# Keep all classes in the package
-keep class tools.rem.workflows_flutter_plugin.** { *; }
-keep class tools.rem.workflows_flutter_plugin.Models.Step.Step { *; }
-keep class tools.rem.workflows_flutter_plugin.Models.Workflow.Workflow { *; }
-keep class tools.rem.workflows_flutter_plugin.Models.WorkflowError { *; }
-keep class tools.rem.workflows_flutter_plugin.WorkflowsFlutterPlugin { *; }
# Keep the Workflow class and its constructors
-keepclassmembers class tools.rem.workflows_flutter_plugin.Models.Workflow.Workflow {
public <init>(...);
}
# Keep the ConfigFacetec class and its constructors
-keep class tools.rem.workflows_flutter_plugin.Models.ConfigFacetec { *; }
-keepclassmembers class tools.rem.workflows_flutter_plugin.Models.ConfigFacetec {
public <init>(...);
}
# Keep the okhttp3 classes
-keep class okhttp3.** { *; }
-keep class okio.** { *; }
# Keep the gson classes
-keep class com.google.gson.** { *; }
# Keep the flutter classes
-keep class io.flutter.** { *; }
-keep class io.flutter.plugins.** { *; }
-keep class io.flutter.util.** { *; }
-keep class io.flutter.embedding.** { *; }
-keep class io.flutter.view.** { *; }
-keep class io.flutter.app.** { *; }
-keep class io.flutter.FlutterInjector { *; }
-keep class **.GeneratedPluginRegistrant { *; }
# Keep the facetec classes
-dontwarn javax.annotation.Nullable
-dontwarn com.facetec.sdk.**
-keep,includecode,includedescriptorclasses class com.facetec.sdk.** { *; }
# Keep the workflows plugin classes and the digitalpersona classes
-keep class com.digitalpersona.** { *; }
# Keep the mediapipe classes
-keep public class com.google.mediapipe.** { *; }
-keep public class com.google.mediapipe.framework.Graph { *; }
-keep public class com.google.common.** { *; }
-keep public interface com.google.common.** { *; }
-keep class com.google.protobuf.** { *; }
-keep class com.google.mediapipe.** { *; }
-keep class com.google.common.** { *; }
-keep class * extends com.google.common.flogger.** {*;}
-keepclassmembers class * extends com.google.protobuf.GeneratedMessageLite {
*;
}
-dontwarn com.google.mediapipe.proto.CalculatorProfileProto$CalculatorProfile
-dontwarn com.google.mediapipe.proto.GraphTemplateProto$CalculatorGraphTemplate
# Keep the cameraview classes
-keep class com.otaliastudios.cameraview.** { *; }
-dontwarn com.otaliastudios.cameraview.**
Ajuste en el AndroidManifest
Para evitar conflictos de nombres en la aplicación, añade la siguiente línea en el elemento <application> del archivo AndroidManifest.xml:
<application
...
tools:replace="android:label">
...
</application>
Organización de Recursos Personalizados
Coloca los assets en la carpeta res de la siguiente forma:
| Carpeta | Tipo de Recurso | Formatos |
|---|---|---|
drawable | Imágenes | .png, .jpeg |
font | Tipografías | .ttf, .otf |
raw | Imágenes vectoriales | .svg |
xml | Textos localizados | .xml |
Configuración Específica para iOS
Requisitos de iOS
- Versión mínima: iOS 13.0
- Versión máxima soportada: iOS 26.0
Configuración del Podfile
En el archivo ios/Podfile, establece la versión mínima en 13 y añade el pod del SDK dentro del target Runner:
platform :ios, '13.0'
target 'Runner' do
# Otras configuraciones y pods
pod 'WorkflowPlugin', podspec: 'https://storage.googleapis.com/workflows-mobile-sdk-artifacts/WorkflowiOS/WorkflowPods/WorkflowsPlugin.podspec?cache=180'
end
Instalación de Dependencias
Desde la carpeta ios de tu proyecto Flutter, ejecuta:
pod install
Permisos en Info.plist
Agrega las siguientes entradas en el archivo Info.plist para solicitar permisos:
<key>NSCameraUsageDescription</key>
<string>3D Liveness Detection by FaceTec.</string>
<key>NSMicrophoneUsageDescription</key>
<string>We need access to your microphone to record audio.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>The example App requires access to the device's location.</string>
Organización de Recursos en iOS
Para usar recursos personalizados, agrégalos directamente a la carpeta del proyecto:
| Tipo de Recurso | Formato | Ubicación |
|---|---|---|
| Textos | .strings | Carpeta del proyecto |
| Imágenes SVG | .svg | Carpeta del proyecto |
| Tipografías | .otf, .ttf | Carpeta del proyecto |
| Imágenes PNG/JPG | .png, .jpg | Asset Catalog |
FAQ
¿Cómo obtengo el workflowId?
El workflowId se obtiene al crear un Workflow mediante nuestra API de Workflows. La respuesta de la API te proporcionará este identificador.
¿Cómo consigo el apiKey y el baseUrl?
El apiKey es proporcionado de forma privada, y el baseUrl suele ser:
https://api.rem.toolspara producción.https://api.test.rem.toolspara pruebas.
¿Cómo obtengo las credenciales de licencia?
Las credenciales de licencia (cert y passphrase) para la función verifyWorkflowsLicense serán compartidas de forma privada por tu administrador de cuenta.



