Öffnen Sie die Erfassung aus einer React-Native-App mit einem nativen Modul.
Ihr Backend erstellt den Prozess in Human Plugin mit einem Journey-Flow und einer callbackUri, die das URL-Schema Ihrer App verwendet. Ein natives Modul öffnet den link aus der Antwort in ASWebAuthenticationSession unter iOS und in Custom Tabs unter Android. Wenn die Erfassung endet, löst das Modul sein Promise auf und die App übernimmt.
Behalten Sie die Human-Plugin-id aus der Create-Antwort. Ihr Backend liest damit das Ergebnis.
Voraussetzungen
- React Native 0.71 oder höher
- Xcode 14 oder höher für iOS
- Android Studio für Android
- Ein für Ihre App eindeutiges URL-Schema, etwa
myapp
1. Den Prozess mit Ihrem Schema erstellen
Ihr Backend sendet das Schema als callbackUri:
{
"flow": "humantoken",
"clientId": "client-a",
"correlationId": "order-1001",
"credential": { "type": "DUI_TYPE_NG_BVN", "value": "<document number>" },
"callbackUri": "myapp://callback"
}
und gibt id und link an die App zurück.
2. Die TypeScript-Bridge erstellen
// 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. Das iOS-Modul implementieren
- Objective-C-Bridge
- Swift-Implementierung
// 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
// ios/CaptureModule.swift
import AuthenticationServices
@objc(CaptureModule)
class CaptureModule: NSObject, ASWebAuthenticationPresentationContextProviding {
private var session: ASWebAuthenticationSession?
@objc func openSession(_ url: String,
resolve: @escaping RCTPromiseResolveBlock,
reject: @escaping RCTPromiseRejectBlock) {
guard let sessionURL = URL(string: url) else {
reject("INVALID_URL", "Invalid URL", nil)
return
}
DispatchQueue.main.async {
let newSession = ASWebAuthenticationSession(
url: sessionURL,
callbackURLScheme: "myapp"
) { callbackURL, error in
self.session = nil
if let callbackURL = callbackURL {
resolve(callbackURL.absoluteString)
} else {
reject("SESSION_ERROR", error?.localizedDescription ?? "Session cancelled", error)
}
}
newSession.presentationContextProvider = self
newSession.prefersEphemeralWebBrowserSession = true
newSession.start()
self.session = newSession
}
}
func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let window = windowScene.windows.first else {
return ASPresentationAnchor()
}
return window
}
@objc static func requiresMainQueueSetup() -> Bool { return true }
}
4. Das Android-Modul implementieren
Fügen Sie die Abhängigkeit in android/app/build.gradle hinzu:
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()
}
Registrieren Sie es in MainApplication.kt:
override fun getPackages(): List<ReactPackage> =
PackageList(this).packages.apply {
add(CapturePackage())
}
Verarbeiten Sie die Rückkehr in 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. Ihr Schema unter Android registrieren
In 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. Die Erfassung starten
import { Capture } from './modules/CaptureModule';
try {
await Capture.openSession(link);
// Die Erfassung ist beendet. Bitten Sie Ihr Backend, das Ergebnis
// mit GET /v1/processes/{id} über die Human-Plugin-id zu lesen.
} catch {
// Die Person hat die Sitzung geschlossen.
}
Zusammenfassung
| Datei | Zweck |
|---|---|
src/modules/CaptureModule.ts | TypeScript-Bridge |
ios/CaptureModule.m | Objective-C-Deklaration |
ios/CaptureModule.swift | iOS: ASWebAuthenticationSession |
android/.../CaptureModule.kt | Android: Custom Tabs |
android/.../CapturePackage.kt | Paketregistrierung |
android/.../MainApplication.kt | Fügt das Paket hinzu |
android/.../MainActivity.kt | Verarbeitet die Rückkehr |
AndroidManifest.xml | Intent-Filter |