Hi everybody! I want to show you how to implement a simple interaction between VueJs webview and native Apps and vice-versa.
Introduction
During my job I need to create some webview and make some interaction with native Android and iOS App.
I did it with some javascript function to send some message and manage it to make some operation.
During this article, we develop an interaction to open native Camera and comeback from native app to webview.
The javascript function that we develop is it:
- openCamera
- pictureAcquired
So let's start.
Web view Vue Js
Before we start you need to install Vue Js on your environment, I advise seeing the documentation at this site VueJs.
After that we can create our project with this command:
vue create webview
Now we can start to create our application.
Here an example of the MyWebview
component
<template>
<div class="hello">
<h1>My Webview</h1>
<p>Response app</p>
<h3>{{msg}}</h3>
<button type="button" class="btn btn-expand btn-primary" @click="next()">Open Camera</button>
</div>
</template>
<script>
import * as appService from '../appService.js'
export default {
name: 'MyWebview',
props: {
msg: ""
},
},
data(){
return{
msg:""
}
},
methods:{
pictureAcquired(msg){
console.log("msg",msg);
this.msg = msg;
},
next(){
appService.openCamera();
},
mounted(){
},
watch:{
msg: function (msgNew, msgOld) {
console.log('new: %s, old: %s', msgNew, msgOld)
},
},
beforeMount(){
//Create interface between Webview and Native application
window['MyWebview'] = {
components: this,
pictureAcquired: (msg) => this.pictureAcquired(msg),
};
}
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
The first operation is add this method that native app Android or IOS can invoked to send some data:
beforeMount(){
window['MyWebview'] = {
components: this,
pictureAcquired: (msg) => this.pictureAcquired(msg),
};
}
It's important to create a page inside a javascript window with the name of the component that you want to link with a native app and add the function for the interaction. Note that it's important to add this event during beforeMount() VueJs lifecycle because it is necessary to expose it before the creation of components inside the webview.
This operation is not enough we need to create an interface inside a javascript file and import it inside the index.html file. We call it native.js.
var nativeApp;
function pictureAcquired(msg) {
window.MyWebview.pictureAcquired(msg);
}
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
<script type="text/javascript" src="<%= BASE_URL %>external_resource/native.js"></script>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
After that i you want to create an interaction from webview to native app you need to define a method inside the VueJs component that invoked a method inside appService.js file like that:
export function openCamera(){
console.log("openCamera")
// Call to Android App
if (window.nativeApp) window.nativeApp.funnelReady();
// Call to IOS App
else if ((window['webkit']) && ( window['webkit'].messageHandlers) && (( window['webkit'].messageHandlers.nativeApp))) window['webkit'].messageHandlers.nativeApp.postMessage({"openCamera": {}});
}
openCamera() define two types of interaction with Android and IOS native device because these two Operating Systems have a different interaction with webview. Everybody had the same connection point the name of javascript interface that defines the interaction point between webview and native app. This interface in this example is nativeApp but it should be named as you want but it must be the same inside the native Application.
Testing
Now we can test our application and enjoy it.
So we can start the application with simple npm command on the projects main root :
npm run serve
After that inside the browser console we can see
console.log("openCamera")
So our application calls the native app javascript and function.
Now we can emulate the response of the native application typing inside the browser console this:
pictureAcquired("pictureAcquired");
After that our application print on the browser console the changes of watcher:
new: Picture acquired, old:
I hope you'll enjoy this article. A special thanks goes to my team-mates for their precious advice.
For additional details about the code listed in this article, here's the link to the repository with the VueJS project and a demo Android application I wrote for you all to test it.
Happy coding!
Top comments (3)
Thank you!! it helps me a lot!!
Thank you !
👏👏👏🚀🚀 Good job!