React Native
Integrieren Sie die Human Token Journey in Ihre React Native-App über ein natives Modul.
Die Integration verwendet ein natives Modul, das an ASWebAuthenticationSession auf iOS und Custom Tabs auf Android delegiert. Wenn die Journey abgeschlossen ist, löst das native Modul das Promise mit der Callback-URL auf.
Voraussetzungen
- React Native 0.71 oder höher
- Xcode 14+ für iOS
- Android Studio für Android
- Ein eindeutiges URL-Schema für Ihre App (z. B.
myapp)
Schritt 1: URL-Schema definieren
Wählen Sie ein eindeutiges Schema (z. B. myapp). Dies wird als callbackUri beim Erstellen des Prozesses verwendet:
callbackUri: myapp://callback
Schritt 2: TypeScript-Bridge erstellen
// src/modules/UnicoModule.ts
import { NativeModules } from 'react-native';
const { UnicoModule } = NativeModules;
if (!UnicoModule) {
throw new Error('UnicoModule not found. Make sure the native module is linked correctly.');
}
export const Unico = {
openSession: (url: string): Promise<string> => UnicoModule.openSession(url),
};
Schritt 3: Natives iOS-Modul implementieren
- Objective-C bridge
- Swift implementation
// ios/UnicoModule.m
#import <React/RCTBridgeModule.h>
@interface RCT_EXTERN_MODULE(UnicoModule, NSObject)
RCT_EXTERN_METHOD(openSession:(NSString *)url
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject)
@end
// ios/UnicoModule.swift
import AuthenticationServices
@objc(UnicoModule)
class UnicoModule: 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 }
}
Schritt 4: Natives Android-Modul implementieren
Fügen Sie die Abhängigkeit zu android/app/build.gradle hinzu:
implementation("androidx.browser:browser:1.5.0")
// android/app/src/main/java/<your.package>/UnicoModule.kt
package com.yourapp
import android.content.Intent
import android.net.Uri
import androidx.browser.customtabs.CustomTabsIntent
import com.facebook.react.bridge.*
class UnicoModule(private val reactContext: ReactApplicationContext) :
ReactContextBaseJavaModule(reactContext) {
private var pendingPromise: Promise? = null
override fun getName() = "UnicoModule"
@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
}
}
}
// UnicoPackage.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 UnicoPackage : ReactPackage {
override fun createNativeModules(ctx: ReactApplicationContext): List<NativeModule> =
listOf(UnicoModule(ctx))
override fun createViewManagers(ctx: ReactApplicationContext): List<ViewManager<*, *>> =
emptyList()
}
Registrieren Sie in MainApplication.kt:
override fun getPackages(): List<ReactPackage> =
PackageList(this).packages.apply {
add(UnicoPackage())
}
Behandeln Sie Weiterleitungen in MainActivity.kt:
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
intent.data?.let { uri ->
if (uri.scheme == "myapp") {
val module = reactInstanceManager
.currentReactContext
?.getNativeModule(UnicoModule::class.java)
module?.handleRedirectUrl(uri)
}
}
}
Schritt 5: AndroidManifest.xml konfigurieren
<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>
Schritt 6: Journey starten
import { Unico } from './modules/UnicoModule';
const resultUrl = await Unico.openSession(processLink);
// resultUrl = myapp://callback?id=...
Dateiübersicht
| Datei | Zweck |
|---|---|
src/modules/UnicoModule.ts | TypeScript-Bridge |
ios/UnicoModule.m | Objective-C-Deklaration |
ios/UnicoModule.swift | iOS — ASWebAuthenticationSession |
android/.../UnicoModule.kt | Android — Custom Tabs |
android/.../UnicoPackage.kt | Paketregistrierung |
android/.../MainApplication.kt | Paketintegration |
android/.../MainActivity.kt | Weiterleitungs-URL-Behandlung |
AndroidManifest.xml | Intent-Filter |