Nativo
Nuestro SDK Nativo de Workflows para Android e iOS permite una experiencia más eficiente y segura para el usuario final. El SDK de Workflows de Nativo permite a los desarrolladores de aplicaciones móviles integrar la funcionalidad de Workflows en sus aplicaciones nativas de Android e iOS.
iOS
La integración del SDK de Workflows en tu aplicación iOS es un proceso sencillo que consta de los siguientes pasos:
Requisitos
- iOS 15.1 - 26.0
- Xcode 14.0+
Configuración
Instalación de CocoaPods
Para integrar el SDK de Workflows, primero asegúrate de que tu Podfile esté configurado para soportar la versión mínima de iOS requerida:
platform :ios, '15.1'
target 'TuApp' do
use_frameworks!
pod 'WorkflowController', :podspec => 'https://storage.googleapis.com/workflows-mobile-sdk-artifacts/WorkflowiOS/WorkflowController/WorkflowsController.podspec'
end
Si no tienes acceso al repositorio del SDK, por favor contacta a tu administrador de cuenta o a soporte, ya que necesitarás acceso al repositorio privado del SDK.
Agrega el siguiente bloque post_install en tu Podfile. Asegúrate de modificar Pods-TestWorkflowsiOS por el target de tu aplicación (debe conservar el prefijo Pods- antes del nombre del proyecto):
post_install do |installer|
system("mv Pods/WorkflowController/MediaPipeTasks*.xcframework Pods/")
installer.pods_project.targets.each do |target|
if target.name == 'Pods-TuApp' # Reemplaza TuApp con el nombre de tu proyecto
group = target.project.main_group.find_subpath("Pods/WorkflowController", true)
%w(MediaPipeTasksVision.xcframework MediaPipeTasksCommon.xcframework).each do |fw|
ref = group.new_file(fw)
ref.source_tree = 'SOURCE_ROOT'
target.frameworks_build_phase.add_file_reference(ref)
end
end
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = "arm64"
config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
end
end
installer.pods_project.save
end
Abre una terminal, navega al directorio de tu proyecto y ejecuta el siguiente comando para instalar el SDK:
pod install
Configuración de Build Settings
En los Build Settings del proyecto, en la sección Build Options, establece User Script Sandboxing en NO.
Configuración de Permisos en Info.plist
Es necesario declarar los permisos que tu aplicación requiere. Añade las siguientes claves en tu archivo Info.plist con descripciones adecuadas sobre cómo tu app usa estos recursos:
<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 devices location.</string>
Recursos Personalizados
Para usar recursos personalizados en tu aplicación, 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 |
Uso
Importación del SDK
Para usar el SDK en tu código, primero debes importarlo:
import WorkflowSDK
Verificación de Licencia
Antes de iniciar un workflow, debes verificar la licencia del SDK:
WorkflowController.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.
Configuración de Personalización
Puedes personalizar la apariencia del SDK mediante WorkflowCustomization:
let workflowCustomization = WorkflowCustomization(
textLocalization: WorkflowCustomization.TextLocalization(
localization: "Localizable.strings"
),
textFont: WorkflowCustomization.TextFont(
headerFont: "Oswald-Bold.ttf",
bodyFont: "Oswald-Regular.ttf",
buttonFont: "Merriweather-Bold.ttf"
),
theme: WorkflowCustomization.Theme(
primaryColor: "#ec2d01",
secondaryColor: "#f59680",
buttonPrimaryColor: "#ec2d01",
buttonSecondaryColor: "#f59680",
buttonTextPrimaryColor: "#fbd5cc",
buttonTextSecondaryColor: "#f9c0b2",
backgroundColor: "#460d00",
facetecOverlayColor: "#761600",
showHeaderLogo: true
),
images: WorkflowCustomization.Images(
logo: "logo.png",
cameraPermissions: "camera_permissions.png",
uploadFaceScan: "upload_face.png",
uploadFaceSuccess: "success.png",
uploadFaceError: "error.png",
photoMathId: "id.png",
cameraActiveTorch: "flash_on.png",
cameraInactiveTorch: "flash_off.png",
fingerPrint: "fingerprint.png",
successPage: "success.svg",
errorPage: "error.svg",
unavailablePage: "unavailable.svg",
locationPage: "location.svg",
biometricSignPage: "biometric_sign.svg",
enrollFingerprintPage: "enroll_fingerprint.svg",
enrollBasicPage: "enroll_basic.svg",
enrollFullPage: "enroll_full.svg",
authPage: "auth.svg",
livenessPage: "liveness.svg",
faceEnrollment3dPage: "face_enrollment_3d.svg"
)
)
Inicialización del WorkflowController
Inicializa el WorkflowController con la URL base, las API keys y la personalización:
let workflowController = WorkflowController(
baseUrl: "https://api.rem.tools",
remApiKey: "tu_rem_api_key",
publicKey: "tu_public_api_key",
workflowCustomization: workflowCustomization
)
Iniciar un Workflow
Para iniciar un workflow, usa el método start con el ID del workflow que deseas iniciar:
workflowController.start(workflowId: "workflow_id") { (success: Bool, error: WorkflowError?) in
if success {
print("Workflow iniciado")
} else {
print("Error al iniciar el workflow: \(String(describing: error))")
}
}
Manejo de Eventos de Workflow
Puedes escuchar eventos de workflow mediante closures:
workflowController.onStepEvent() { (step: Step) in
print("Evento de paso: \(step.status)")
}
workflowController.onWorkflowEvent() { (workflow: Workflow) in
print("Workflow UUID: \(workflow.uuid)")
}
Si tienes alguna duda o problema con la integración del SDK, por favor contacta a soporte.
Android
La integración del SDK de Workflows en tu aplicación Android es un proceso sencillo que consta de los siguientes pasos:
Requisitos
- Android API 24 - 36
- Android Studio Hedgehog+
Configuración
Configuración de settings.gradle
En el archivo settings.gradle (Project Settings), cambia el modo de repositorios a PREFER_PROJECT:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_PROJECT)
}
Configuración de Repositorios
En el archivo build.gradle (app), declara de dónde se obtendrán las dependencias:
repositories {
google()
mavenCentral()
maven {
url "https://us-central1-maven.pkg.dev/gendra-services/workflows-mobile"
credentials {
username = "_json_key"
password = file("tu_archivo_credenciales.json").text
}
}
}
Si no tienes acceso al repositorio o al archivo de credenciales, por favor contacta a tu administrador de cuenta o a soporte, ya que necesitarás acceso al repositorio privado del SDK.
Implementación de Dependencias
Agrega las dependencias de Workflows en el archivo build.gradle de tu módulo:
dependencies {
// SDK Implementation
implementation ('tools.rem.workflows:sdk:1.17.5@aar') { transitive = true }
// Required dependencies
implementation 'com.getkeepsafe.relinker:relinker:1.4.5'
implementation "androidx.window:window:1.0.0"
implementation 'com.google.android.gms:play-services-location:21.3.0'
implementation 'com.squareup.okhttp3:okhttp:5.1.0'
implementation 'com.squareup.okio:okio:3.16.0'
implementation 'com.google.code.gson:gson:2.13.1'
implementation "com.bugsnag:bugsnag-android:6.17.0"
implementation 'com.google.mediapipe:tasks-vision:0.10.26.1'
// Media3 dependencies
implementation "androidx.media3:media3-exoplayer:1.4.1"
implementation "androidx.media3:media3-exoplayer-hls:1.4.1"
implementation "androidx.media3:media3-exoplayer-dash:1.4.1"
implementation "androidx.media3:media3-exoplayer-rtsp:1.4.1"
implementation "androidx.media3:media3-exoplayer-smoothstreaming:1.4.1"
// Camera dependencies
implementation "com.otaliastudios:cameraview:2.7.2"
implementation "androidx.camera:camera-core:1.4.2"
implementation "androidx.camera:camera-camera2:1.4.2"
implementation "androidx.camera:camera-lifecycle:1.4.2"
implementation "androidx.camera:camera-video:1.4.2"
implementation "androidx.camera:camera-view:1.4.2"
implementation "androidx.camera:camera-extensions:1.4.2"
// Other dependencies
implementation 'com.google.guava:guava:27.1-android'
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2'
}
Compatibilidad con el tema de la aplicación
Para evitar conflictos con el tema de la aplicación, agrega el siguiente atributo en el archivo AndroidManifest.xml:
<application
...
tools:replace="android:theme, android:usesCleartextTraffic">
Configuración de Release Build
Para ejecutar en modo release, agrega lo siguiente en el archivo build.gradle a nivel de android:
android {
// ...
buildTypes {
release {
shrinkResources false
// otras configuraciones...
}
}
aaptOptions {
noCompress "tflite", "task"
}
sourceSets {
main {
assets.srcDirs += 'src/main/assets'
}
}
}
Configuración de ProGuard
Agrega las siguientes reglas al archivo proguard-rules.pro:
# Keep the io.flutter.plugin.** package provided by Flutter
-dontwarn io.flutter.plugin.**
# The android.** package is provided by the OS at runtime.
-dontwarn android.**
# Rules for the Workflows Flutter
-keep class tools.rem.workflows_flutter_plugin.** { *; }
-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 * extends com.google.common.flogger.** {*;}
-keep class com.google.protobuf.** { *; }
-keepclassmembers class * extends com.google.protobuf.GeneratedMessageLite.** { *; }
-dontwarn com.google.mediapipe.proto.CalculatorProfileProto$CalculatorProfile
-dontwarn com.google.mediapipe.proto.GraphTemplateProto$CalculatorGraphTemplate
Recursos Personalizados
Para usar recursos personalizados, agrega los assets en la carpeta res según su tipo:
| Carpeta | Tipo de Recurso | Formatos |
|---|---|---|
drawable | Imágenes | .png, .jpeg |
font | Tipografías | .ttf, .otf |
raw | Imágenes vectoriales | .svg |
xml | Textos localizados | .xml |
Uso
Importación del SDK
Para usar el SDK en tu código Kotlin, primero debes importarlo:
import tools.rem.workflows.WorkflowsActivity
import tools.rem.workflows.model.WorkflowCustomization
import tools.rem.workflows_flutter_plugin.Models.Step.Step
import tools.rem.workflows_flutter_plugin.Models.Workflow.Workflow
import tools.rem.workflows_flutter_plugin.Models.WorkflowError
Verificación de Licencia
Antes de iniciar un workflow, debes verificar la licencia del SDK:
WorkflowsActivity.verifyWorkflowsLicense("tu_certificado", "tu_passphrase")
Las credenciales de licencia (cert y passphrase) serán compartidas de forma privada por tu administrador de cuenta.
Configuración de Personalización
Puedes personalizar la apariencia del SDK mediante WorkflowCustomization:
val workflowCustomization = WorkflowCustomization(
textLocalization = WorkflowCustomization.TextLocalization(
localization = R.xml.localizable
),
textFont = WorkflowCustomization.TextFont(
headerFont = R.font.oswald_bold,
bodyFont = R.font.oswald_regular,
buttonFont = R.font.merriweather_bold
),
theme = WorkflowCustomization.Theme(
primaryColor = "#ec2d01",
secondaryColor = "#f59680",
buttonPrimaryColor = "#ec2d01",
buttonSecondaryColor = "#f59680",
buttonTextPrimaryColor = "#fbd5cc",
buttonTextSecondaryColor = "#f9c0b2",
backgroundColor = "#460d00",
facetecOverlayColor = "#761600",
showHeaderLogo = true
),
images = WorkflowCustomization.Images(
logo = R.drawable.logo,
cameraPermissions = R.drawable.camera_permissions,
uploadFaceScan = R.drawable.upload_face,
uploadFaceSuccess = R.drawable.success,
uploadFaceError = R.drawable.error,
photoMathId = R.drawable.id,
cameraActiveTorch = R.drawable.flash_on,
cameraInactiveTorch = R.drawable.flash_off,
fingerPrint = R.drawable.fingerprint,
successPage = R.raw.success,
errorPage = R.raw.error,
unavailablePage = R.raw.unavailable,
locationPage = R.raw.location,
biometricSignPage = R.raw.biometric_sign,
enrollFingerprintPage = R.raw.enroll_fingerprint,
enrollBasicPage = R.raw.enroll_basic,
enrollFullPage = R.raw.enroll_full,
authPage = R.raw.auth,
livenessPage = R.raw.liveness,
faceEnrollment3dPage = R.raw.face_enrollment_3d
)
)
Inicialización del WorkflowController
Inicializa el WorkflowsActivity con la URL base, las API keys y la personalización:
val workflowController = WorkflowsActivity(
"https://api.rem.tools", // Base URL
"tu_rem_api_key", // REM API Key
"tu_public_api_key", // Public API Key
workflowCustomization // Personalización
)
Iniciar un Workflow
Para iniciar un workflow, usa el método start con el ID del workflow y el contexto de la actividad:
workflowController.start(
"workflow_id",
this
) { success: Boolean, error: WorkflowError? ->
if (success) {
Log.d("Workflow", "Workflow iniciado exitosamente")
} else {
Log.e("Workflow", "Error al iniciar el workflow: $error")
}
}
Manejo de Eventos de Workflow
Puedes escuchar eventos de workflow mediante callbacks:
workflowController.onStepEvent { step: Step ->
Log.d("Workflow", "Evento de paso: ${step}")
}
workflowController.onWorkflowEvent { workflow: Workflow ->
Log.d("Workflow", "Evento de workflow: ${workflow}")
}
Ejemplo Completo
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Verificar licencia
WorkflowsActivity.verifyWorkflowsLicense("tu_certificado", "tu_passphrase")
// Configurar personalización
val workflowCustomization = WorkflowCustomization(
// ... configuración de personalización
)
// Inicializar controller
val workflowController = WorkflowsActivity(
"https://api.rem.tools",
"tu_rem_api_key",
"tu_public_api_key",
workflowCustomization
)
// Iniciar workflow
workflowController.start("workflow_id", this) { success, error ->
Log.i("Workflows", "Start result: $success, error: $error")
}
// Escuchar eventos de pasos
workflowController.onStepEvent { step ->
Log.d("Workflows", "Step event: $step")
}
// Escuchar eventos de workflow
workflowController.onWorkflowEvent { workflow ->
Log.d("Workflows", "Workflow event: $workflow")
}
}
}
Si tienes alguna duda o problema con la integración del SDK, por favor contacta a soporte.



