Integration for iOS
Documentation
This guide explains how to embed our Smart Assistant chatbot in your iOS app using a WKWebView. The integration consists of two parts:
- An HTML page that loads the Smart Assistant web component.
- A SwiftUI view that hosts the
WKWebViewand bridges native ↔ JavaScript communication (e.g. to close the assistant).
1. Create the HTML page
Add an HTML file (smart_assistant.html) to your app bundle. It loads our launcher.js script and declares the <smart-assistant> web component.
On iOS, the native ↔ JavaScript bridge works through window.webkit.messageHandlers. The Swift code below registers a handler named smartAssistantClose, so the HTML must call window.webkit.messageHandlers.smartAssistantClose.postMessage(...) when the assistant closes.
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>Smart Assistant</title>
<script src="https://sa-media.usizy.es/smart-assistant/launcher.js"></script>
</head>
<body>
<smart-assistant language="en" api-key="YOUR_API_KEY" opened hide-minimize></smart-assistant>
<script>
document.addEventListener('DOMContentLoaded', function () {
const sa = document.querySelector('smart-assistant')
// Escuchar el evento de cierre del componente (equivalente al Android bridge)
sa.addEventListener('close', function () {
if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.smartAssistantClose) {
window.webkit.messageHandlers.smartAssistantClose.postMessage('close')
}
})
})
</script>
</body>
</html>
2. Recommended attributes of :
| Attribute | Description |
|---|---|
| language | Interface language (e.g. en, es). |
| api-key | Your API key. Replace YOUR_API_KEY with the key provided by usizy. |
| opened | Opens the assistant automatically when the page loads. |
| hide-minimize | Hides the minimize button (recommended for full-screen WebView usage). |
The close event listener is essential: it calls window.Android.close(), which is the JavaScript bridge that lets the web component close the native Android screen.
3. Create the SwiftUI view
The following example uses SwiftUI. It wraps a native WKWebView inside a UIViewRepresentable, configures the required settings, and registers a script message handler (smartAssistantClose) so the web component can trigger native navigation.
import SwiftUI
import WebKit
struct SmartAssistantView: View {
@Environment(\.dismiss) private var dismiss
var body: some View {
SmartAssistantWebView(onClose: { dismiss() })
.ignoresSafeArea(edges: .bottom)
.navigationTitle("Smart Assistant")
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(Color(red: 0.427, green: 0.231, blue: 0.478), for: .navigationBar)
.toolbarBackground(.visible, for: .navigationBar)
.toolbarColorScheme(.dark, for: .navigationBar)
}
}
struct SmartAssistantWebView: UIViewRepresentable {
let onClose: () -> Void
func makeCoordinator() -> Coordinator {
Coordinator(onClose: onClose)
}
func makeUIView(context: Context) -> WKWebView {
let configuration = WKWebViewConfiguration()
// Allow inline media playback without requiring a user gesture
configuration.allowsInlineMediaPlayback = true
configuration.mediaTypesRequiringUserActionForPlayback = []
// Register the JS → native bridge named "smartAssistantClose"
let contentController = WKUserContentController()
contentController.add(context.coordinator, name: "smartAssistantClose")
configuration.userContentController = contentController
let webView = WKWebView(frame: .zero, configuration: configuration)
webView.backgroundColor = .clear
webView.isOpaque = false
webView.scrollView.bounces = false
webView.navigationDelegate = context.coordinator
// Enable Safari Web Inspector while debugging (iOS 16.4+)
#if DEBUG
if #available(iOS 16.4, *) {
webView.isInspectable = true
}
#endif
// Load the local HTML asset bundled with the app
if let htmlURL = Bundle.main.url(forResource: "smart_assistant", withExtension: "html") {
webView.loadFileURL(htmlURL, allowingReadAccessTo: htmlURL.deletingLastPathComponent())
}
return webView
}
func updateUIView(_ uiView: WKWebView, context: Context) {}
class Coordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler {
let onClose: () -> Void
init(onClose: @escaping () -> Void) {
self.onClose = onClose
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction,
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
decisionHandler(.allow)
}
// Receives messages posted from JavaScript via window.webkit.messageHandlers
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "smartAssistantClose" {
DispatchQueue.main.async {
self.onClose()
}
}
}
}
}
4. Key configuration explained
WKWebView configuration
These settings are required for the Smart Assistant to work correctly:
| Setting | Why it is needed |
|---|---|
| allowsInlineMediaPlayback = true | Plays audio/video inline instead of forcing full-screen playback. |
| mediaTypesRequiringUserActionForPlayback = [] | Allows media to start without an explicit user gesture. |
| userContentController.add(_:name:) | Registers the smartAssistantClose JS → native message bridge. |
| loadFileURL(_:allowingReadAccessTo:) | Loads the local HTML and grants read access to its folder (and resources). |
| webView.isInspectable = true (DEBUG) | Enables Safari Web Inspector for debugging on iOS 16.4+. |
####JavaScript bridge (smartAssistantClose)
The Coordinator conforms to WKScriptMessageHandler and is registered with the name smartAssistantClose. When the user closes the assistant, the web component emits a close event, the HTML calls window.webkit.messageHandlers.smartAssistantClose.postMessage(‘close’), and userContentController(_:didReceive:) invokes your onClose() callback to dismiss the view. Note: Message handlers may be delivered off the main thread depending on the call site, so any UI work (like dismissing the view) is dispatched to the main thread with DispatchQueue.main.async.
5. Present the view in your navigation
Present the view from your navigation stack, for example with a NavigationLink or a sheet:
NavigationLink("Open Smart Assistant") {
SmartAssistantView()
}
Or as a modal sheet:
.sheet(isPresented: $isAssistantPresented) {
NavigationStack {
SmartAssistantView()
}
}
Add the HTML to your app target
Make sure smart_assistant.html is added to your app target so it is copied into the bundle: Drag the file into your Xcode project. In the dialog, check Copy items if needed. Confirm the file appears under Target → Build Phases → Copy Bundle Resources. If you load remote resources over plain HTTP (not recommended), you will also need to configure App Transport Security (ATS) in Info.plist. Loading our launcher.js over HTTPS requires no extra ATS configuration.
Sample App
Check our sample app for iOS