Zum Hauptinhalt springen
Flutter-Capture

Öffnen Sie die Erfassung aus einer Flutter-App mit einem Platform Channel.

Markdown

Ihr Backend erstellt den Prozess in Human Plugin mit einem Journey-Flow und einer callbackUri, die das URL-Schema Ihrer App verwendet. Ein MethodChannel öffnet den link aus der Antwort in ASWebAuthenticationSession unter iOS und in Custom Tabs unter Android. Es wird kein externes Paket benötigt.

Behalten Sie die Human-Plugin-id aus der Create-Antwort. Ihr Backend liest damit das Ergebnis.

Voraussetzungen​

  • Flutter 3 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. Den Dart-Service erstellen​

// lib/services/capture_service.dart
import 'package:flutter/services.dart';

class CaptureService {
static const _channel = MethodChannel('capture_plugin');

/// Gibt true zurück, wenn die Erfassung beendet wurde, und false, wenn die Person sie geschlossen hat.
Future<bool> open(String link) async {
try {
final result = await _channel.invokeMethod<String>('openSession', {'url': link});
return result != null;
} on PlatformException {
return false;
}
}
}

3. Das iOS-Plugin implementieren​

// ios/Runner/CapturePlugin.swift
import Flutter
import AuthenticationServices

class CapturePlugin: NSObject, FlutterPlugin, ASWebAuthenticationPresentationContextProviding {
private var session: ASWebAuthenticationSession?

static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "capture_plugin", binaryMessenger: registrar.messenger())
let instance = CapturePlugin()
registrar.addMethodCallDelegate(instance, channel: channel)
}

func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
guard call.method == "openSession",
let args = call.arguments as? [String: Any],
let urlString = args["url"] as? String,
let url = URL(string: urlString) else {
result(FlutterMethodNotImplemented)
return
}

let newSession = ASWebAuthenticationSession(
url: url,
callbackURLScheme: "myapp"
) { callbackURL, error in
self.session = nil
if let callbackURL = callbackURL {
result(callbackURL.absoluteString)
} else {
result(FlutterError(code: "SESSION_ERROR",
message: error?.localizedDescription ?? "Session cancelled",
details: nil))
}
}
newSession.presentationContextProvider = self
newSession.prefersEphemeralWebBrowserSession = true
newSession.start()
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
}
}

Registrieren Sie es in AppDelegate.swift:

CapturePlugin.register(with: self.registrar(forPlugin: "CapturePlugin")!)

4. Das Android-Plugin implementieren​

Fügen Sie die Abhängigkeit in android/app/build.gradle hinzu:

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

import android.net.Uri
import androidx.browser.customtabs.CustomTabsIntent
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel

class CapturePlugin : FlutterPlugin, MethodChannel.MethodCallHandler, ActivityAware {
private var channel: MethodChannel? = null
private var binding: ActivityPluginBinding? = null
private var pendingResult: MethodChannel.Result? = null

override fun onAttachedToEngine(flutterBinding: FlutterPlugin.FlutterPluginBinding) {
channel = MethodChannel(flutterBinding.binaryMessenger, "capture_plugin")
channel?.setMethodCallHandler(this)
}

override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
if (call.method == "openSession") {
val url = call.argument<String>("url") ?: return result.error("MISSING_URL", "URL is required", null)
pendingResult = result
val activity = binding?.activity ?: return result.error("NO_ACTIVITY", "No activity", null)
CustomTabsIntent.Builder().build().launchUrl(activity, Uri.parse(url))
} else {
result.notImplemented()
}
}

fun handleRedirect(uri: Uri) {
if (uri.scheme == "myapp") {
pendingResult?.success(uri.toString())
pendingResult = null
}
}

override fun onAttachedToActivity(binding: ActivityPluginBinding) { this.binding = binding }
override fun onDetachedFromActivity() { binding = null }
override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) { this.binding = binding }
override fun onDetachedFromActivityForConfigChanges() { binding = null }
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { channel = null }
}

Registrieren Sie es und verarbeiten Sie die Rückkehr in MainActivity.kt:

override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
flutterEngine.plugins.add(CapturePlugin())
}

override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
intent.data?.let { uri ->
if (uri.scheme == "myapp") {
val plugin = flutterEngine?.plugins?.get(CapturePlugin::class.java) as? CapturePlugin
plugin?.handleRedirect(uri)
}
}
}

5. Ihr Schema registrieren​

In Info.plist:

<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
</dict>
</array>

6. Die Erfassung starten​

final ended = await CaptureService().open(link);

if (ended) {
// Die Erfassung ist beendet. Bitten Sie Ihr Backend, das Ergebnis
// mit GET /v1/processes/{id} über die Human-Plugin-id zu lesen.
} else {
// Die Person hat die Sitzung geschlossen.
}

Zusammenfassung​

DateiZweck
lib/services/capture_service.dartDart-MethodChannel-Service
ios/Runner/CapturePlugin.swiftiOS: ASWebAuthenticationSession
ios/Runner/AppDelegate.swiftPlugin-Registrierung
android/.../CapturePlugin.ktAndroid: Custom Tabs
android/.../MainActivity.ktPlugin-Registrierung und Verarbeitung der Rückkehr
Info.plistiOS-URL-Schema
AndroidManifest.xmlAndroid-Intent-Filter