Jsbridge Technology of interaction between H5 and native

Source: Internet
Author: User

First, the principle article

Below are the underlying interactions between iOS and Android and JavaScript, respectively.

Ios

Before explaining the principles, first to understand the iOS UIWebView components, first look at Apple's official introduction:

You can use the UIWebView class to embed Web content in your application. To doing so, you simply create a UIWebView object, attach it to a window, and send it a request to load Web content. can also use this class to move back and forward in the history of webpages, and can even set some Web content Pro Perties programmatically.

The above means that UIWebView is an object that can load Web pages, has a browsing history function, and is programmable for the contents of the loaded Web page. Frankly UIWebView has a browser-like function, we can use it to open the page, and do some custom functions, such as the JS can be transferred to a method can be taken to the mobile phone GPS information.

However, it is important to note that the browser controls and UIWebView components used by the Safari browser are not the same, and there is a significant difference in performance. Fortunately, when Apple released IOS8, a new Wkwebview component was added, and if your app only considers support for iOS8 and above, then you can use the browser control.

The native UIWebView class provides the following properties and methods

Property:

    • Loading: Whether it is in the loading
    • Cangoback:a Boolean value indicating whether the receiver can move backward. (Read only)
    • Cangoforward:a Boolean value indicating whether the receiver can move forward. (Read only)
    • Request:the URL Request identifying the location of the content to load. (read-only)

Method:

    • Loaddata:sets The main page contents, MIME type, content encoding, and base URL.
    • Loadrequest: Loading Network content
    • loadHTMLString: Loading the local HTML file
    • Stoploading: Stop loading
    • GoBack: Back
    • GoForward: Forward
    • Reload: Reload
    • Stringbyevaluatingjavascriptfromstring: Executes a JS script and returns the execution result
Native (objective-c or Swift) call the JavaScript method

Native calls the JavaScript language, which is implemented by means of a UIWebView component, which stringByEvaluatingJavaScriptFromString returns the execution result of the JS script.

// Swiftwebview.stringByEvaluatingJavaScriptFromString("Math.random()")// OC[webView stringByEvaluatingJavaScriptFromString:@"Math.random();"];

From the above code can be seen that it is actually called the window next object, if we want to let native to invoke our JS write method, then this method will window be able to access the next. But from a global point of view, we just have to expose an object such as Jsbridge to native call, so here you can do a simple encapsulation of native code:

//下面为伪代码webview.setDataToJs(somedata);webview.setDataToJs = function(data) { webview.stringByEvaluatingJavaScriptFromString("JSBridge.trigger(event, data)")}
JavaScript calls the native (Objective-c or Swift) method

In turn, JavaScript calls native, and there is no ready-made API to use directly, but it needs to be implemented indirectly through some means. UIWebView has a feature: all network requests initiated within the UIWebView can be notified through the delegate function at the native layer. In this way, we can launch a custom network request within UIWebView, usually in this format: jsbridge://methodname?param1=value1&param2=value2

So in UIWebView's delegate function, as long as we find the address that is the beginning of the jsbridge://, we do not load the content, but instead execute the corresponding invocation logic.

There are two ways to initiate such a network request: 1. by Localtion.href;2. Through the IFRAME mode;
The problem with Location.href is that if we modify the value of window.location.href several times in a row, the native layer can only receive the last request, and the previous request will be ignored.

Using the IFRAME mode, to evoke the native app's sharing component as an example, the simple closure is as follows:

var url = ‘jsbridge://doAction?title=分享标题&desc=分享描述&link=http%3A%2F%2Fwww.baidu.com‘;var iframe = document.createElement(‘iframe‘);iframe.style.width = ‘1px‘;iframe.style.height = ‘1px‘;iframe.style.display = ‘none‘;iframe.src = url;document.body.appendChild(iframe);setTimeout(function() { iframe.remove();}, 100);

The webview can then intercept the request and parse out the corresponding methods and parameters. As shown in the following code:

FuncWebView(Webview:uiwebview, Shouldstartloadwithrequest request:nsurlrequest, Navigationtype:uiwebviewnavigationtype)Bool {Print"Shouldstartloadwithrequest")Let URL = Request.UrlLet scheme = URL?. SchemeLet method = URL?. HostLet query = URL?. QueryIf URL! =Nil && Scheme = ="Jsbridge" {Print"Scheme = =\ (Scheme) ")Print"Method = =\ (method) ")Print"Query = =\ (query) ")Switch method! {Case"GetData":Self.getdata ()Case "PutData": self.putdata () case Span class= "hljs-string" > "Gotowebview": self.gotowebview ()  Case  "gotonative": self.gotonative () case  "doAction": self.doaction () case  "confignative":  Self.confignative () default: print (  "default")} return false} else {return true}}         
Android

In Android, native and JS communicate in a similar way to iOS, and iOS is supported by the schema in Android.

JavaScript calls native mode

There are currently three ways to call native in Android:

1. The shouldOverrideUrlLoading URL protocol is parsed using the schema method. This JS is called in the same way as iOS, using an IFrame to invoke the native code.
2. By injecting the native JS code directly into the WebView page, use the addJavascriptInterface method to achieve.
The following are implemented on Android:

class JSInterface {    @JavascriptInterface //注意这个代码一定要加上 public String getUserData() { return "UserData"; }}webView.addJavascriptInterface(new JSInterface(), "AndroidJS");

The code above is to inject the object into the Window object of the page AndroidJS . You can call it directly in JS.

alert(AndroidJS.getUserData()) //UserDate

3. Using the Prompt,console.log,alert method, these three methods for JS is the attribute of the original, in the Android WebView this layer can rewrite these three methods. Generally we use prompt, because this in JS use not much, used to and native communication side effect is relatively few.

ClassYouzanwebchromeclientExtendswebchromeclient { @Override public boolean onjsprompt (WebView view, String URL, String message, string defaultvalue, jspromptresult result) {//here you can handle the prompt of JS, return result by result}  @Override public Span class= "Hljs-keyword" >boolean onconsolemessage ( Consolemessage consolemessage) {}  @Override public boolean onjsalert  (WebView view, string URL, string message, jsresult result) {}}     
Native calling JavaScript mode

In Android it is called using WebView loadUrl , such as:

// 调用js中的JSBridge.trigger方法webView.loadUrl("javascript:JSBridge.trigger(‘webviewReady‘)");
Second, the packaging of the library JS call native

We understand the underlying principle of JS and native communication, so we can encapsulate a basic communication method doCall to block the differences between Android and iOS.

Youzanjsbridge = {Docall:functionfunctionname, data, callback) {var _this =ThisResolving continuous invocation issuesif (This.lastcalltime && (Date.now ()-This.lastcalltime) <{SetTimeout (function{_this.docall (functionname, data, callback);},100);Return }This.lastcalltime =Date.now (); data = Data | | {};if (callback) {$.extend (data, {Callback:callback}); }if (Ua.isios ()) {$.each (data,functionKey, value) {if ($.isplainobject (value) | | $.isarray (value)) {Data[key] =Json.stringify (value); } });var url = args.addparameter (' youzanjs://' + functionname, data);var iframe =Document.createelement (' iframe '); Iframe.style.width = ' 1px '; iframe.style.height =  ' 1px '; iframe.style.display =  ' none '; iframe.src = URL; document.body.appendchild (iframe); SetTimeout (function (100); Span class= "Hljs-keyword" >else if (Ua.isandroid ()) { Window.androidjs && window.androidjs[functionname] && window.androidjs[functionname" (json.stringify (data));} else {console.error (" did not obtain platform information, failed to fetch API " ); } }} 

Above the Android side we used the Addjavascriptinterface method to inject a Androidjs object.

Project General Method Abstraction

In the project practice, we are gradually abstracting out some common methods, which basically can meet the needs of the project. As shown below:

1.getData (datatype, callback, extra) H5 get data from the native app

Usage Scenario: This method can be called when H5 needs to get some data from the native app.

Parameters type whether you must Example Values Description
DataType String Is UserInfo Data type
Callback Function Is callback function
Extra Object Whether Data objects passed to the native app

Example code:

JSBridge.getData(‘userInfo‘,function(data) {    console.log(data);});
2.putData (datatype, data) H5 tells native app some data

Usage scenario: H5 tells the native app some data that you can call this method.

Parameters type whether you must Example Values Description
DataType String Is UserInfo Data type
Data Object Is {username: ' Zhangsan ', age:20} Data objects passed to the native app

Example code:

JSBridge.putData(‘userInfo‘, {    username: ‘zhangsan‘,    age: 20});
3.gotoWebview (URL, page, data) Native app opens a new WebView window to open the page
Parameters type whether you must Example Values Description
Url String Is Http://www.youzan.com Web page link address, usually just pass the URL parameter can be
Page String Whether Web Web page page type, default to Web
Data Object Whether Extra Parameter Object

Example code:

// 示例1:打开一个网页JSBridge.gotoWebview(‘http://www.youzan.com‘);// 示例2:打开一个网页,并且传递额外的参数给Native APPJSBridge.gotoWebview(‘http://www.youzan.com‘, ‘goodsDetail‘, { goods_id: 10000, title: ‘这是商品的标题‘, desc: ‘这是商品的描述‘});
4.gotoNative (page, data) jumps from the H5 page to a native interface of the native app
Parameters type whether you must Example Values Description
Page String Is LoginPage Native page identifiers, such as LoginPage
Data Object Whether {username: ' Zhangsan ', age:20} Extra Parameter Object

Example code:

// 示例1:打开Native APP登录页面JSBridge.gotoNative(‘loginPage‘);// 示例2:打开Native APP登录页面,并且传递用户名给Native APPJSBridge.gotoNative(‘loginPage‘, {    username: ‘张三‘});
Some actions on the 5.doAction (action, data) feature
Parameters type whether you must Example Values Description
Action String Is Copy Types of operation functions, such as sharing, copying
Data Object Whether {content: ' This is what you want to copy '} Additional parameters

Example code:

// 示例1:调用Native APP复制一段文本到剪切板JSBridge.doAction(‘copy‘, {    content: ‘这是要复制的内容‘});// 示例2:调用Native APP的分享组件,分享当前网页到JSBridge.doAction(‘share‘, { title: ‘分享标题‘, desc: ‘分享描述‘, link: ‘http://www.youzan.com‘, imgs_url: ‘http://wap.koudaitong.com/v2/common/url/create?type=homepage&index%2Findex=&kdt_id=63077&alias=63077‘});
Third, debugging using Safari for UIWebView debugging

(1) First you need to open the Safari debug mode, in the Safari menu, select "Safari" → "Preference" → "advanced", tick the "Show Develop menu in menu bar" option, as shown in.

(2) Open the debug mode of the real or iphone simulator, open the Settings screen in the real machine or iphone simulator, select "Safari" → "Advanced" → "Web Inspector", select on, as shown in.

(3) Connect the real machine via USB to the computer, or open the simulator, Safari "Develop" menu will be more than the corresponding menu items.

(4) After Safari connects to UIWebView, we can directly modify HTML, CSS, and debug JavaScript directly in Safari.

Iv. Reference Links
    • UIWebView Class Reference
    • Wkwebview Class Reference
    • Https://github.com/marcuswestin/WebViewJavascriptBridge

Jsbridge Technology of interaction between H5 and native

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.