Saltar al contenido principal
Captura en React Native

Abre la captura desde una app React Native con un módulo nativo.

Markdown

Tu backend crea el proceso en Human Plugin con un flujo Journey y un callbackUri que usa el esquema de URL de tu app. Un módulo nativo abre el link de la respuesta en ASWebAuthenticationSession en iOS y en Custom Tabs en Android. Cuando la captura termina, el módulo resuelve su promesa y la app retoma el control.

Conserva el id de Human Plugin de la respuesta de la creación. Tu backend lee el resultado con él.

Requisitos previos​

  • React Native 0.71 o posterior
  • Xcode 14 o posterior para iOS
  • Android Studio para Android
  • Un esquema de URL único para tu app, como myapp

1. Crea el proceso con tu esquema​

Tu backend envía el esquema como callbackUri:

{
"flow": "humantoken",
"clientId": "client-a",
"correlationId": "order-1001",
"credential": { "type": "DUI_TYPE_NG_BVN", "value": "<document number>" },
"callbackUri": "myapp://callback"
}

y devuelve id y link a la app.

2. Crea el puente en TypeScript​

// src/modules/CaptureModule.ts
import { NativeModules } from 'react-native';

const { CaptureModule } = NativeModules;

if (!CaptureModule) {
throw new Error('CaptureModule not found. Make sure the native module is linked correctly.');
}

export const Capture = {
openSession: (url: string): Promise<string> => CaptureModule.openSession(url),
};

3. Implementa el módulo de iOS​

// ios/CaptureModule.m
#import <React/RCTBridgeModule.h>

@interface RCT_EXTERN_MODULE(CaptureModule, NSObject)
RCT_EXTERN_METHOD(openSession:(NSString *)url
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject)
@end

4. Implementa el módulo de Android​

Agrega la dependencia a android/app/build.gradle:

implementation("androidx.browser:browser:1.5.0")
// android/app/src/main/java/<your.package>/CaptureModule.kt
package com.yourapp

import android.net.Uri
import androidx.browser.customtabs.CustomTabsIntent
import com.facebook.react.bridge.*

class CaptureModule(private val reactContext: ReactApplicationContext) :
ReactContextBaseJavaModule(reactContext) {

private var pendingPromise: Promise? = null

override fun getName() = "CaptureModule"

@ReactMethod
fun openSession(url: String, promise: Promise) {
pendingPromise = promise
currentActivity?.runOnUiThread {
CustomTabsIntent.Builder().build()
.launchUrl(currentActivity!!, Uri.parse(url))
} ?: promise.reject("NO_ACTIVITY", "No current activity")
}

fun handleRedirectUrl(uri: Uri) {
if (uri.scheme == "myapp") {
pendingPromise?.resolve(uri.toString())
pendingPromise = null
}
}
}
// CapturePackage.kt
package com.yourapp

import com.facebook.react.ReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ViewManager

class CapturePackage : ReactPackage {
override fun createNativeModules(ctx: ReactApplicationContext): List<NativeModule> =
listOf(CaptureModule(ctx))
override fun createViewManagers(ctx: ReactApplicationContext): List<ViewManager<*, *>> =
emptyList()
}

Regístralo en MainApplication.kt:

override fun getPackages(): List<ReactPackage> =
PackageList(this).packages.apply {
add(CapturePackage())
}

Gestiona el regreso en MainActivity.kt:

override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
intent.data?.let { uri ->
if (uri.scheme == "myapp") {
val module = reactInstanceManager
.currentReactContext
?.getNativeModule(CaptureModule::class.java)
module?.handleRedirectUrl(uri)
}
}
}

5. Registra tu esquema en Android​

En AndroidManifest.xml:

<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-permission android:name="android.permission.CAMERA" />

<activity android:name=".MainActivity" ...>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="myapp" android:host="callback" />
</intent-filter>
</activity>

6. Inicia la captura​

import { Capture } from './modules/CaptureModule';

try {
await Capture.openSession(link);
// La captura terminó. Pide a tu backend que lea el resultado
// con GET /v1/processes/{id}, usando el id de Human Plugin.
} catch {
// La persona cerró la sesión.
}

Resumen​

ArchivoPropósito
src/modules/CaptureModule.tsPuente en TypeScript
ios/CaptureModule.mDeclaración en Objective-C
ios/CaptureModule.swiftiOS: ASWebAuthenticationSession
android/.../CaptureModule.ktAndroid: Custom Tabs
android/.../CapturePackage.ktRegistro del paquete
android/.../MainApplication.ktAgrega el paquete
android/.../MainActivity.ktGestiona el regreso
AndroidManifest.xmlIntent filter