Binding Webview to Native App Functions
Handling the interaction between webview programs and the app

The webview might want to access some native features. Like opening a deeplink, showing the share drawer, etc.
callback
native method should be binded with any webview.- The webview will pass
eventJSON
to the callback function.
The webview will call this function in the following ways -
app.callback(eventJSON); //Android
webkit.messageHandlers.callback.postMessage(eventJSON); // iOS
Android(Java)
iOS(Swift)
Android(Kotlin)
React Native
Flutter
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.util.Log;
import org.json.JSONObject;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView webView = (WebView)findViewById(R.id.web_view);
webView.loadUrl("https://app-markk.customerglu.com/program"); // webview url
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new WebViewJavaScriptInterface(this), "app"); // **IMPORTANT** call it app
}
/*
* JavaScript Interface. Web code can access methods in here
* (as long as they have the @JavascriptInterface annotation)
*/
public class WebViewJavaScriptInterface{
private Context context;
/*
* Need a reference to the context in order to sent a post message
*/
public WebViewJavaScriptInterface(Context context){
this.context = context;
}
/*
* This method can be called from Android. @JavascriptInterface
* required after SDK version 17.
*/
@JavascriptInterface
// **IMPORTANT** call it callback
public void callback(String message){
JSONObject data = new JSONObject(message);
// data has the event information
Log.d(data);
}
}
}
import UIKit
import WebKit
import Foundation
class ViewController: UIViewController , WKScriptMessageHandler{
@IBOutlet weak var mWebKitView: WKWebView!
@IBOutlet weak var mEdtTxt: UITextField!
var mNativeToWebHandler : String = "callback" // **IMPORTANT** call it callback
var webviewUrl: String = "https://app-markk.customerglu.com/program" // webview url
override func viewDidLoad() {
super.viewDidLoad()
let myURL = URL(string: webviewUrl)
let myRequest = URLRequest(url: myURL!)
mWebKitView.load(myRequest)
let contentController = WKUserContentController()
mWebKitView.configuration.userContentController = contentController
mWebKitView.configuration.userContentController.add(self, name: mNativeToWebHandler)
}
// message handler
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == mNativeToWebHandler {
// message.body holds JSON of the event
let jsonMessageString: String = message.body as? String;
let jsonDict = try JSONSerialization.jsonObject(with: jsonMessageString) as? NSDictionary
// // jsonDict has the event information
print(jsonDict)
}
}
}
package com.customerglu.kotlinwebviewnativecomm
import android.content.Context
import android.os.Bundle
import android.webkit.JavascriptInterface
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
// TODO: Replace url with the url for your program/campaign.
private val url = "<Provide-Your-campaign-url here>"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
exampleWebView.settings.javaScriptEnabled = true
exampleWebView.addJavascriptInterface(JSComm(this),"app")
exampleWebView.loadUrl(url)
}
/**
* Receive message from webview
*/
class JSComm(val context: Context){
@JavascriptInterface
fun callback(message:String){
// Capture message from webview and print as toast
Toast.makeText(context,message, Toast.LENGTH_LONG).show()
}
}
}
import React from "react";
import WebView, { WebViewMessageEvent } from "react-native-webview";
import { StyleSheet, Text, View } from "react-native";
export function GluWebView({ url }: { url: string }) {
/* Callback for the WebView */
function onWebViewEvent(event: WebViewMessageEvent) {
const data: IWebViewEvent = JSON.parse(event.nativeEvent.data);
console.log(data);
}
return (
<View style={styles.container}>
<WebView
source={{ uri: url }}
onMessage={onWebViewEvent} /* Pass the callback (line: 34) defined as props */
renderLoading={() => (
<Text style={styles.text}>Loading Webview...</Text>
)}
renderError={() => (
<Text style={styles.text}>Error Loading Webview...</Text>
)}
startInLoadingState
style={{ marginTop: 20 }}
/>
</View>
);
}
type IWebViewEvent = IOpenDeepLinkEvent | ICloseEvent | IShareEvent;
interface IOpenDeepLinkEvent {
eventName: "OPEN_DEEPLINK";
data: {
deepLink: string;
name: string;
};
}
interface ICloseEvent {
eventName: "CLOSE";
}
interface IShareEvent {
eventName: "SHARE";
data: {
channelName: "WHATSAPP" | "SMS" | "EMAIL" | "OTHERS";
text: string;
image: string;
};
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "stretch",
justifyContent: "center",
},
text: {
fontSize: 30,
},
});
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class MyWebView extends StatefulWidget {
@override
WebState createState() => WebState();
}
class WebState extends State<MyWebView> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
top: true,
child: WebView(
initialUrl: "CAMPAIGN_URL", //Need to put Campaign url
javascriptMode: JavascriptMode.unrestricted, //IMPORTANT for enablig javascript
javascriptChannels: <JavascriptChannel>[
JavascriptChannel(
name: 'app', // Name is "app"
onMessageReceived: (s) {
print(s.message); // s.message contains event data like {"eventName":"CLOSE","data":null}
}),
].toSet(),
),
));
}
}
- The native callback function should be able to identify the event using
eventName
property present in the JSON. - The
data
property contains data relevant to thateventName
.
Last modified 4mo ago