Aller au contenu principal
Capture React Native

Ouvrez la capture depuis une application React Native avec un module natif.

Markdown

Votre back-end crée le processus dans Human Plugin avec un flux Journey et un callbackUri qui utilise le scheme d'URL de votre application. Un module natif ouvre le link de la réponse dans ASWebAuthenticationSession sur iOS et dans Custom Tabs sur Android. Lorsque la capture se termine, le module résout sa promesse et l'application reprend la main.

Conservez l'id Human Plugin de la réponse de création. Votre back-end lit le résultat avec cet id.

Prérequis​

  • React Native 0.71 ou version ultérieure
  • Xcode 14 ou version ultérieure pour iOS
  • Android Studio pour Android
  • Un scheme d'URL propre à votre application, tel que myapp

1. Créer le processus avec votre scheme​

Votre back-end envoie le scheme comme callbackUri :

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

et renvoie id et link à l'application.

2. Créer le bridge 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. Implémenter le module 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. Implémenter le module Android​

Ajoutez la dépendance à 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()
}

Enregistrez-le dans MainApplication.kt :

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

Gérez le retour dans 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. Enregistrer votre scheme sur Android​

Dans 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. Démarrer la capture​

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

try {
await Capture.openSession(link);
// La capture est terminée. Demandez à votre back-end de lire le résultat
// avec GET /v1/processes/{id}, en utilisant l'id Human Plugin.
} catch {
// La personne a fermé la session.
}

Récapitulatif​

FichierRôle
src/modules/CaptureModule.tsBridge TypeScript
ios/CaptureModule.mDéclaration Objective-C
ios/CaptureModule.swiftiOS : ASWebAuthenticationSession
android/.../CaptureModule.ktAndroid : Custom Tabs
android/.../CapturePackage.ktEnregistrement du package
android/.../MainApplication.ktAjoute le package
android/.../MainActivity.ktGère le retour
AndroidManifest.xmlIntent filter