Method of use

  1. native
class ViewController: UIViewController {
    let webView = .
    var bridge: WKWebviewJavascriptBridge!
    .
    override func viewDidLoad(a) {
        super.viewDidLoad()
        bridge = WKWebViewJavascriptBridge(webview: webView)
        bridge.register(handlerName: "xxx") { params, callback in}}.
    func click(a) {
        bridge.call(handlerName: "xxxx") { params, callback in}}}Copy the code
  1. vuetransform
function setupWebViewJavascriptBridge(callback) {
  if (window.WebViewJavascriptBridge) {
    return callback(window.WebViewJavascriptBridge);
  }
  if (window.WVJBCallbacks) {
    return window.WVJBCallbacks.push(callback);
  }
  window.WVJBCallbacks = [callback];
  let WVJBIframe = document.createElement("iframe");
  WVJBIframe.style.display = "none";
  WVJBIframe.src = "https://__bridge_loaded__";
  document.documentElement.appendChild(WVJBIframe);
  setTimeout(() = > {
    document.documentElement.removeChild(WVJBIframe);
  }, 0);
}
const callhandler = (name, data, callback) = > {
  setupWebViewJavascriptBridge(function(bridge) {
    bridge.callHandler(name, data, callback);
  });
};
const registerhandler = (name, callback) = > {
  setupWebViewJavascriptBridge(function(bridge) {
    bridge.registerHandler(name, function(data, responseCallback) {
      callback(data, responseCallback);
    });
  });
};
export { registerhandler, callhandler };
Copy the code
  1. vueThe use of
import { callhandler, registerhandler } from './bridge'; .mounted() {
    registerhandler(<name>, () = >{}); },methods: {
    callMobile() {
        callhandler(<name>, params, (result) = >{}); }}Copy the code

Or in main.js

import Bridge from './bridge.js'
Vue.prototype.$bridge = Bridge
this.$bridge.callhandler(...)
this.$bridge.register(...)
Copy the code

Native communication

How do we interact directly with each other natively when we’re not using this three-party library?

Js call native

  1. js
// If messageBody has and must have an argument, pass null if not
// 
      
        is the function name negotiated with the mobile
      
window.webkit.messageHandlers.<name>.postMessage(<messageBody>)
Copy the code
  1. native
class ViewController: UIViewController {
    override func viewdidLoad(a) {
        super.viewDidLoad()
        // One detail that needs to be noted here is the circular reference problem
        webView?.configuration.userContentController.add(LeakAvoider(delegate: self), name: <name>)}// Remember to release
    deinit {
        webView?.configuration.userContentController.removeScriptMessageHandler(forName: <name>)}}extension ViewController: WKScriptMessageHandler {
    public func userContentController(_ userContentController: WKUserContentController.didReceive message: WKScriptMessage) {
    if message.name = = <name> {
        // doSomething(message.body)}}Copy the code

Native call JS

  1. native
webview.evaluateJavaScript(<name>, completionHandler: completion)
Copy the code
  1. js
window.<name> = function(param) {
    // doSomething()
}
Copy the code

The principle of

Initialize the

  1. jscallwindow.webkit.messageHandlers.iOS_Native_InjectJavascript.postMessage(null)
  2. iOSperformwebView.evaluateJavascript(javascript: WKWebViewJavascriptBridgeJS, ...)

There will be messageHandlers and responseCallbacks in both js and native, and then the corresponding function execution will be matched according to the string, and there will be an increment of uniqeID to record the corresponding callback.