Skip to main content
Unveilydocs

Custom Bridge

Build your own native bridge modules

Overview

If you need a unique native feature that the built-in Bridge (window.unveilyBridge) doesn't cover, you can add your own native bridge. MainActivity (Android) and the app entry code are areas you edit directly, so you register your own interface there.

Advanced · platform-specific extension

This is an advanced extension where you write Kotlin/Swift yourself. The built-in glue (window.unveilyBridge) does not provide a generic .call() dispatcher for running arbitrary actions. Instead, you inject your own native object into the WebView and call that object directly from the web.

Both Android and iOS support custom bridges. The registration mechanism differs per platform.

Android — register a @JavascriptInterface

Create your bridge class and inject it into the WebView from MainActivity.

// app/src/main/java/.../bridge/MyNativeBridge.kt
class MyNativeBridge(private val context: Context) {

    // Called from JavaScript as window.MyNativeBridge.myAction(...)
    @JavascriptInterface
    fun myAction(paramsJson: String): String {
        val params = JSONObject(paramsJson)
        val input = params.optString("input")

        val result = doNativeWork(input)   // native processing

        return JSONObject().apply {
            put("success", true)
            put("result", result)
        }.toString()
    }
}
// MainActivity.kt — inject where you configure the WebView
webView.addJavascriptInterface(MyNativeBridge(this), "MyNativeBridge")

From the web, call the injected object directly. @JavascriptInterface methods return a string synchronously, so parse the result JSON yourself.

// Web → call your injected native object directly
const raw = window.MyNativeBridge.myAction(JSON.stringify({ input: "hello" }));
const result = JSON.parse(raw);
console.log(result.result);

iOS — register a WKScriptMessageHandler

On iOS, register a message handler on the WKUserContentController.

// Register the handler when configuring the WebView
let controller = webView.configuration.userContentController
controller.add(self, name: "myAction")

// Receive messages
func userContentController(_ controller: WKUserContentController,
                           didReceive message: WKScriptMessage) {
    guard message.name == "myAction",
          let body = message.body as? [String: Any] else { return }
    let input = body["input"] as? String ?? ""
    let result = doNativeWork(input)
    // Deliver the result back to the web via a callback (e.g. evaluateJavaScript)
    webView.evaluateJavaScript("window.onMyActionResult({ result: '\(result)' })")
}
// Web → iOS message handler (postMessage is async — receive the result via a callback)
window.webkit.messageHandlers.myAction.postMessage({ input: "hello" });

window.onMyActionResult = function (result) {
  console.log(result.result);
};

Maintenance tip

Custom bridges live in your own code area, so they are not overwritten by Unveily SDK updates. Still, prefer window.unveilyBridge for anything the built-in Bridge already covers, and keep custom code to the minimum you actually need.

On this page