Aplikacje mobilne: czat w WebView
Jak wbudować reactive.chat w aplikację na iOS lub Androida – przez stronę do osadzenia /embed/SITE_KEY w WKWebView lub WebView, z tożsamością przez JavaScript, przesyłaniem plików, przyciskiem Wstecz i powiadomieniami push przez webhooki.
Dla aplikacji nie ma natywnego SDK. Zamiast tego twoja aplikacja ładuje stronę zbudowaną właśnie dla WebView:
https://reactive.chat/embed/SITE_KEY
Strona nie ma ramki, nawigacji ani launchera: widżet wypełnia ekran i jest od razu otwarty. To ten sam czat co na twojej stronie – ten sam projekt, ten sam wygląd, ta sama skrzynka odbiorcza. Klucz witryny znajdziesz w koncie w sekcji Projekt → Instalacja.
Właściwości strony:
- tylko dla aktywnych projektów; w przeciwnym razie 404,
viewport-fit=coveri safe area – pole wiadomości leży nad paskiem przy dolnej krawędzi,- tło w kolorze twojej marki, dopóki widżet się nie załaduje,
X-Robots-Tag: noindexiframe-ancestors 'none'– strona należy do WebView, a nie do<iframe>innej strony,- język według języka urządzenia.
iOS (WKWebView)
import WebKit
let konf = WKWebViewConfiguration()
konf.allowsInlineMediaPlayback = true // inaczej odtwarzacz pełnoekranowy zasłania czat
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")!))
Rozciągnij WebView na całą powierzchnię, a nie w obrębie Safe Area Layout Guide – strona sama uwzględnia odstęp.
Android (WebView)
val web = findViewById<WebView>(R.id.chat)
web.settings.javaScriptEnabled = true
web.settings.domStorageEnabled = true // obowiązkowe: bez tego nie ma sesji
web.settings.mediaPlaybackRequiresUserGesture = false
web.webViewClient = WebViewClient() // inaczej otwiera się przeglądarka systemowa
web.loadUrl("https://reactive.chat/embed/SITE_KEY")
domStorageEnabled nie jest opcjonalne: widżet zapisuje swoje identyfikatory w pamięci WebView. Bez tego każde uruchomienie zaczyna nową rozmowę.
Przekazanie zalogowanego użytkownika
Nigdy przez adres. Hash w URL trafia do historii, logów i nagłówków Referer. Przekaż tożsamość po załadowaniu przez JavaScript. userHash oblicza twój serwer (Identyfikacja odwiedzających) – sekret nie powinien trafić do pakietu aplikacji, bo aplikacje da się rozebrać na części. Niech twoja aplikacja pobiera te trzy wartości z twojego serwera przy logowaniu.
// Android, w onPageFinished
web.evaluateJavascript(
"""ReactiveChat("identify",{userId:"$id",name:"$name",userHash:"$hash",exp:$exp});""",
null)
// iOS, w webView(_:didFinish:)
web.evaluateJavaScript(
"ReactiveChat(\"identify\",{userId:\"\(id)\",name:\"\(name)\",userHash:\"\(hash)\",exp:\(exp)});")
Pamiętaj o poprawnym escapowaniu wartości dla JavaScriptu (najprościej serializując je w aplikacji jako JSON). Wcześniejsze wywołanie również zadziała: kolejka ReactiveChat.q przyjmie je, zanim widżet zostanie załadowany.
Co jest inaczej w WebView
- Powiadomienia push nie pochodzą z czatu. Jeśli twoja aplikacja ma docierać do użytkownika przy zamkniętym czacie, skonfiguruj webhook na
message.createdi wysyłaj push samodzielnie. - Przesyłanie plików działa na Androidzie dopiero wtedy, gdy twoja aplikacja przekaże wybór plików dalej (
WebChromeClient.onShowFileChooser); iOS robi to sam. - Przycisk Wstecz (Android): strona nie ma własnej historii. Traktuj czat jak ekran swojej aplikacji i zamykaj go zamiast wywoływać
web.goBack(). - Tło: nie usuwaj WebView przy przejściu aplikacji w tło. Widżet sam łączy się ponownie po przerwach i dosyła zbuforowane wiadomości (Transport).
- Zgoda: na stronie do osadzenia nie ma platformy zgód; widżet startuje więc bez zgody i początkowo zapisuje swoje identyfikatory tylko na czas życia WebView (Ochrona danych). Sprawdź w swojej aplikacji, czy rozmowa przetrwa ponowne uruchomienie aplikacji.
Zdarzenia w aplikacji
Zdarzenia widżetu możesz przekazać do aplikacji przez most JavaScript, np. aby ustawić plakietkę z liczbą nieprzeczytanych wiadomości:
// Android: wcześniej zarejestruj web.addJavascriptInterface(Bruecke(), "App")
web.evaluateJavascript(
"ReactiveChat('on','unread',function(e){ App.ungelesen(e.count); });", null)
Dalej: Smart Answer
Τελευταία ενημέρωση: