모바일 앱: WebView의 채팅
iOS·Android 앱의 reactive.chat 연동: WKWebView 또는 WebView에서 /embed/SITE_KEY 페이지 사용, JavaScript 신원 전달, 파일 업로드, 뒤로 버튼과 웹훅 푸시.
앱용 네이티브 SDK는 없습니다. 대신 WebView용으로 만든 페이지를 앱에서 로드합니다.
https://reactive.chat/embed/SITE_KEY
페이지에는 프레임, 내비게이션과 채팅 버튼이 없습니다. 위젯은 화면을 채우고 즉시 열려 있습니다. 웹사이트와 같은 프로젝트, 같은 디자인, 같은 받은 편지함을 사용하는 동일한 채팅입니다. 사이트 키는 계정의 프로젝트 → 설치에 있습니다.
페이지 특성:
- 활성 프로젝트만 가능하며 그 외에는 404입니다.
viewport-fit=cover와 안전 영역을 사용해 입력란이 하단 막대 위에 놓입니다.- 위젯이 준비될 때까지 브랜드 색상을 배경으로 사용합니다.
X-Robots-Tag: noindex와frame-ancestors 'none'를 설정합니다. 페이지는 WebView용이며 다른 웹사이트의<iframe>용이 아닙니다.- 언어는 기기 언어를 따릅니다.
iOS(WKWebView)
import WebKit
let konf = WKWebViewConfiguration()
konf.allowsInlineMediaPlayback = true // otherwise the full-screen player pulls the chat away
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")!))
WebView는 안전 영역 레이아웃 가이드 안이 아닌 전체 영역에 배치합니다. 페이지가 여백을 직접 처리합니다.
Android(WebView)
val web = findViewById<WebView>(R.id.chat)
web.settings.javaScriptEnabled = true
web.settings.domStorageEnabled = true // required: no session without it
web.settings.mediaPlaybackRequiresUserGesture = false
web.webViewClient = WebViewClient() // otherwise the system browser opens
web.loadUrl("https://reactive.chat/embed/SITE_KEY")
domStorageEnabled는 선택 사항이 아닙니다. 위젯은 WebView 저장소에 ID를 저장하므로 없으면 실행할 때마다 새 대화를 시작합니다.
로그인 사용자 전달
주소로 전달하지 않습니다. URL의 해시는 기록, 로그와 Referer 헤더에 남습니다. 로드 후 JavaScript로 신원을 전달합니다. 서버가 userHash를 계산합니다(방문자 식별). 앱은 분석할 수 있으므로 시크릿을 앱 패키지에 넣어서는 안 됩니다. 앱이 로그인할 때 서버에서 세 값을 가져오도록 합니다.
// 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)});")
JavaScript에 맞게 값을 올바르게 이스케이프합니다. 앱에서 JSON으로 직렬화하는 방법이 가장 간단합니다. 미리 호출해도 됩니다. ReactiveChat.q 큐가 위젯 로드 전에도 받습니다.
WebView에서 달라지는 점
- 푸시 알림은 채팅에서 오지 않습니다. 채팅이 닫혀 있을 때 앱에서 사용자에게 알리려면
message.created웹훅을 설정하고 직접 푸시를 보냅니다. - 파일 업로드는 Android에서 앱이 파일 선택기(
WebChromeClient.onShowFileChooser)를 전달해야 작동합니다. iOS는 자동 처리합니다. - 뒤로 버튼(Android): 페이지에는 자체 기록이 없습니다. 채팅을 앱의 화면으로 취급하고
web.goBack()대신 닫습니다. - 백그라운드: 앱이 백그라운드로 가도 WebView를 폐기하지 않습니다. 위젯은 중단 후 스스로 다시 연결하고 버퍼링한 메시지를 보냅니다(전송).
- 동의: 삽입 페이지에는 동의 플랫폼이 없습니다. 따라서 위젯은 동의 없이 시작하며 초기에는 WebView가 유지되는 동안에만 ID를 저장합니다(개인정보 보호 연동). 앱을 다시 시작해도 대화가 유지되는지 확인합니다.
앱에 이벤트 전달
읽지 않은 메시지 배지를 설정하는 경우처럼 JavaScript 브리지로 위젯의 이벤트를 앱에 전달할 수 있습니다.
// Android: register web.addJavascriptInterface(Bruecke(), "App") beforehand
web.evaluateJavascript(
"ReactiveChat('on','unread',function(e){ App.ungelesen(e.count); });", null)
다음: Smart Answer
최종 업데이트: