美文网首页
H5 与Native的交互方案

H5 与Native的交互方案

作者: 风之化身呀 | 来源:发表于2017-11-11 20:35 被阅读948次

1、前言

App里基本都少不了H5页面,因此JS与Native之间的通信不可避免,最近留意了一些方案,做下总结。

2、iOS与H5通信

iOS有两种webview,ios8以上推出了WKWebView,低于ios8用的是UIWebView,WKWebView性能上优于UIWebView

2.1 、iOS调用H5

Native调用Javascript语言,是通过UIWebView组件的stringByEvaluatingJavaScriptFromString方法来实现的,该方法返回js脚本的执行结果。

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

双方只需要约定好JS端函数名称及参数

2.2、 H5调用iOS

JS调用Native,并没有现成的API可以使用,需要借助iframe来实现。原理是在UIWebView内发起的所有网络请求,都可以通过delegate函数在Native层得到通知。所以只需要劫持该UIWebView内的所有请求(通常是这样的格式:jsbridge://methodName?param1=value1&param2=value2),然后在UIWebView的delegate函数中,只要发现是jsbridge://开头的地址,就不进行内容的加载,转而执行相应的调用逻辑:

// JS 端关键代码
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);

// OC端关键代码
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
        print("shouldStartLoadWithRequest")
        let url = request.URL
        let scheme = url?.scheme
        let method = url?.host
        let query = url?.query

        if url != nil && scheme == "jsbridge" {
            print("scheme == \(scheme)")
            print("method == \(method)")
            print("query == \(query)")

            switch method! {
                case "getData":
                    self.getData()
                case "putData":
                    self.putData()
                case "gotoWebview":
                    self.gotoWebview()
                case "gotoNative":
                    self.gotoNative()
                case "doAction":
                    self.doAction()
                case "configNative":
                    self.configNative()
                default:
                    print("default")
            }

            return false
        } else {
            return true
        }
    }

3、Android与H5通信

3.1 、Android调用H5

在android里是使用webview的loadUrl进行调用的

// 调用js中的JSBridge.trigger方法
webView.loadUrl("javascript:JSBridge.trigger('webviewReady')");

3.2、 H5调用Android

有两种比较好的方式:

  • 和iOS一样,通过iframe(Android端通过shouldOverrideUrlLoading方法对url协议进行解析)
  • 通过在webview页面里直接注入原生js代码方式,使用addJavascriptInterface方法来实现。
    在android里实现如下:
class JSInterface {
    @JavascriptInterface //注意这个代码一定要加上
    public String getUserData() {
        return "UserData";
    }
}
webView.addJavascriptInterface(new JSInterface(), "AndroidJS");  //window对象里注入了AndroidJS对象

JS端可以直接调用:alert(AndroidJS.getUserData()) //UserDate

4、iOS与H5通信的其它方案

基于 callHandler 和 registerHandler的方式,比较干净

  • JS调用Native
        setupWebViewJavascriptBridge(e => {
        e.callHandler("getHttpHeader", {}, function(data) {   //getHttpHeader方法在ios端定义好
            fn(data);
        })
    })
  • Native调用JS
setupWebViewJavascriptBridge(e => {
    e.registerHandler("navBarButtonClicked", (data, responseCallback) => { //H5端注册navBarButtonClicked
        if (data == 'mine') {
            ...
        }
    })
})

//
const setupWebViewJavascriptBridge = e => {
    if (window.WebViewJavascriptBridge)
        return e(WebViewJavascriptBridge);
    if (window.WVJBCallbacks)
        return window.WVJBCallbacks.push(e);
    window.WVJBCallbacks = [e];
    var t = document.createElement("iframe");
    t.style.display = "none";
    t.src = WVJBIframeSrc();
    document.documentElement.appendChild(t);
    setTimeout(function() {
        document.documentElement.removeChild(t)
    }, 0)
};

5、小结

  • iOS调H5(stringByEvaluatingJavaScriptFromString),H5调iOS(iframe,schema协议)
  • Android调H5(webView.loadUrl()),H5调Android(1、iframe;2、addJavascriptInterface)
  • 从可维护性上看,H5端都用iframe方式调用iOS&Android最好
  • 从实际操作上看,H5端需要维护一个专门用于和Native端通信的js库(封装iframe及一些方法定义),俗称SDK;
    Native端需要各自与H5端定义的函数对接。

6、参考文档

1、Web 与 App 数据交互原理和实现
2、WK 与 JS 的那些事
3、H5 与 Native 交互之 JSBridge 技术
4、WebView 开车指南之最全实用案例

相关文章

  • Native与H5交互的那些事

    Native与H5交互的那些事 Native与H5交互的那些事

  • 007.WebView详解

    Native与H5交互的那些事Native与JS相互调用(附JadX反编译)

  • H5 与Native的交互方案

    1、前言 App里基本都少不了H5页面,因此JS与Native之间的通信不可避免,最近留意了一些方案,做下总结。 ...

  • 1.WebView与OC通讯方式

    参考:WK 与 JS 的那些事 WKWebView使用H5 与 Native 交互之 JSBridge 技术 1....

  • 2018-02-07

    OC与H5交互 交互的四种方式 有很多的app直接使用在webview的代理中通过拦截的方式与native进行交互...

  • WebViewJavaScriptBridge

    WebViewJavaScriptBridge Native和H5交互之WebViewJavascriptBrid...

  • 「React Native」react-native-webvi

    一、背景说明: 二、react-native-webview与h5交互 1.rn给h5发事件,可以通过拿到webv...

  • OC与H5交互

    OC与H5交互 一、 方案 I. iOS6的方案 ios6 主要是通过UIWebView来实现交互,可以通过一个第...

  • iOS与H5的交互【WKWebView】

    iOS与H5的交互【WKWebView】 iOS与H5的交互【WKWebView】

  • h5与App原生交互方案

    H5与App原生交互,一般会是前端页面中的JavaScript与App使用的原生开发语言的交互。技术方案应能达到以...

网友评论

      本文标题:H5 与Native的交互方案

      本文链接:https://www.haomeiwen.com/subject/odcgmxtx.html