Mobile Apps: der Chat im WebView
Wie du reactive.chat in eine iOS- oder Android-App einbaust – über die Einbettungsseite /embed/SITE_KEY im WKWebView bzw. WebView, mit Identität per JavaScript, Datei-Uploads, Zurück-Knopf und Push über Webhooks.
Für Apps gibt es kein natives SDK. Stattdessen lädt deine App eine Seite, die genau für einen WebView gebaut ist:
https://reactive.chat/embed/SITE_KEY
Die Seite hat keinen Rahmen, keine Navigation und keinen Launcher: Das Widget füllt den Bildschirm und ist sofort offen. Es ist derselbe Chat wie auf deiner Website – dasselbe Projekt, dieselbe Gestaltung, derselbe Posteingang. Den Site-Key findest du im Konto unter Projekt → Einbau.
Eigenschaften der Seite:
- nur für aktive Projekte; sonst 404,
viewport-fit=coverund Safe Area – das Eingabefeld liegt über dem Balken am unteren Rand,- Hintergrund in deiner Markenfarbe, bis das Widget steht,
X-Robots-Tag: noindexundframe-ancestors 'none'– die Seite gehört in einen WebView, nicht in einen<iframe>einer anderen Website,- Sprache nach der Sprache des Geräts.
iOS (WKWebView)
import WebKit
let konf = WKWebViewConfiguration()
konf.allowsInlineMediaPlayback = true // sonst reisst der Vollbild-Player den Chat weg
let web = WKWebView(frame: .zero, configuration: konf)
web.scrollView.bounces = false
web.scrollView.contentInsetAdjustmentBehavior = .never
web.load(URLRequest(url: URL(string: "https://reactive.chat/embed/SITE_KEY")!))
Lege den WebView über die ganze Fläche, nicht in den Safe-Area-Layout-Guide – die Seite rechnet den Abstand selbst ein.
Android (WebView)
val web = findViewById<WebView>(R.id.chat)
web.settings.javaScriptEnabled = true
web.settings.domStorageEnabled = true // Pflicht: ohne das keine Sitzung
web.settings.mediaPlaybackRequiresUserGesture = false
web.webViewClient = WebViewClient() // sonst oeffnet der Systembrowser
web.loadUrl("https://reactive.chat/embed/SITE_KEY")
domStorageEnabled ist nicht optional: Das Widget legt seine Kennungen im Speicher des WebViews ab. Ohne ihn beginnt jeder Start ein neues Gespräch.
Den angemeldeten Nutzer übergeben
Nie über die Adresse. Ein Hash in einer URL landet im Verlauf, in Protokollen und in Referer-Köpfen. Übergib die Identität nach dem Laden per JavaScript. Den userHash berechnet dein Server (Besucher identifizieren) – das Geheimnis gehört nicht in ein App-Paket, Apps lassen sich auseinandernehmen. Lass deine App die drei Werte beim Anmelden von deinem Server holen.
// Android, in onPageFinished
web.evaluateJavascript(
"""ReactiveChat("identify",{userId:"$id",name:"$name",userHash:"$hash",exp:$exp});""",
null)
// iOS, in webView(_:didFinish:)
web.evaluateJavaScript(
"ReactiveChat(\"identify\",{userId:\"\(id)\",name:\"\(name)\",userHash:\"\(hash)\",exp:\(exp)});")
Achte darauf, Werte für JavaScript korrekt zu maskieren (am einfachsten als JSON aus deiner App serialisieren). Ein früherer Aufruf geht ebenfalls: Die Warteschlange ReactiveChat.q nimmt ihn an, bevor das Widget geladen ist.
Was im WebView anders ist
- Push-Benachrichtigungen kommen nicht vom Chat. Soll deine App den Nutzer bei geschlossenem Chat erreichen, richte einen Webhook auf
message.createdein und schicke den Push selbst. - Dateien hochladen funktioniert unter Android erst, wenn deine App den Dateiwähler weiterreicht (
WebChromeClient.onShowFileChooser); iOS tut das selbst. - Zurück-Knopf (Android): Die Seite hat keine eigene Historie. Behandle den Chat wie einen Bildschirm deiner App und schließe ihn, statt
web.goBack()aufzurufen. - Hintergrund: Wirf den WebView beim Wechsel in den Hintergrund nicht weg. Das Widget verbindet sich nach Unterbrechungen selbst neu und schickt gepufferte Nachrichten nach (Transport).
- Einwilligung: Auf der Einbettungsseite gibt es keine Consent-Plattform; das Widget startet daher ohne Einwilligung und legt seine Kennungen zunächst nur für die Lebensdauer des WebViews ab (Datenschutz-Einbindung). Prüfe in deiner App, ob ein Gespräch einen Neustart der App überdauert.
Ereignisse in die App holen
Die Ereignisse des Widgets kannst du per JavaScript-Brücke in deine App weiterreichen, etwa um ein Abzeichen für ungelesene Nachrichten zu setzen:
// Android: web.addJavascriptInterface(Bruecke(), "App") vorher registrieren
web.evaluateJavascript(
"ReactiveChat('on','unread',function(e){ App.ungelesen(e.count); });", null)
Weiter: Smart Answer
Stand: