Current environment: Xcode10.0 Swift4.2 iOS SDK 12.1

The following is the principle of the implementation code, you can see the reference article + Demo view. Demo: github.com/zColdWater/…

The premise to master

Background overview: With the increasing application of H5 on the App end, H5 students will meet the same Native needs as their Native classmates. At this time, Native students and H5 students need to be able to communicate. So how to find the correct way of communication for ios-based WKWebView?

Here we refer to dsbridge-ios, but if you’ve already seen the source code for this library, you can skip this article. Here I will introduce its JSBridge practice according to DSBridge source code

Some of the necessary methods to use WKWebView can be found here

  1. Know Javascript = = =[call]===> Native

    How to implement Javascript call Native? In fact, Apple already provides this channel, this channel is WKUIDelegate, if you are not clear, you can click here to check

    We’ll mention only one of the methods in WKUIDelegate. The reason for choosing this callback method is that this channel allows Javascript to pass two arguments and get a synchronized return value.

    // A Javascript call to the prompt method triggers the proxy method
    Var result = prompt("AA", "BB")
    func webView(_webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String? , initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping(String?) -> Void) {
        1 / / parameter
        var param1 = prompt //"AA"
        2 / / parameter
        var param2 = defaultText // "BB"
        / / callback result
        completionHandler("Synchronize return value to Javascript")}Copy the code
  2. Understand the Native = = =[call]===> Javascript

    The evaluateJavaScript method is the evaluateJavaScript method that Apple also provides a channel to implement Native Javascript

    We prepare the JS method nativeMessageHandler and then we find a moment in our code where we can call it and trigger the Javascript method.

    function nativeMessageHandler(method,param) {
        // 'action1','param1'
        console.log(method,param) 
    }
    Copy the code
    / / Native code
    
    // Note: this method does not respond until the entire WebView is loaded.
    webview.evaluateJavaScript("nativeMessageHandler('action1', 'param1')", completionHandler: { (feedback, error) in
    })
    Copy the code

Understand dsbridge-ios principle

The reason why we are looking at dsbridge-ios is because it is a better implementation of JSBridge based on WKWebView for most of the scenarios we are developing, so let’s see how it works and it will help us to use this library.

We’re only going to look at two of them and see how they work, so if you haven’t used them you might want to check them out and come back. DSBridge-IOS

The following are two ways for DSBridge to interact with Native: one is for JS to call Native methods, the other is for Native to call JS methods

Function callSyn() {function callSyn() {

/ / corresponding native method name: ` testSyn ` / / parameters: ` Hello ` / / types: synchronous invocations dsBridge. Call (" testSyn ", "Hello")} ` ` ` implementation principle of * * * * : In ` DSBridge ` inside is through [` WKUIDelegate `] (https://zcoldwater.github.io/blog/article/ios/wkwebview/) to realize synchronous calls, JS will by calling ` prompt ` method, Invoke the following method in the 'Native' layer's 'WKUIDelegate' proxy protocol Swift func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String? , initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {} * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * And return to the callback function 'completionHandler' to implement the 'Native' return value to the 'JS' method.Copy the code

Function callAsyn() {function callAsyn() {

// Call dsbridge. call("testAsyn","hello", function (value) {// Get the native callback argument. Console. log(value)})} ' '** In ` DSBridge ` inside is through [` WKUIDelegate `] (https://zcoldwater.github.io/blog/article/ios/wkwebview/) and ` evaluateJavaScript ` ways to implement ` JS 'calls' Native' and then 'Native' calls back to 'JS'. First, the 'JS' method calls' Native 'with additional callback parameters.' JS 'registers the callback function in the' JS 'global, for example, hanging in the global call' BlockA ', and then proceeds to trigger the 'WKUIDelegate' protocol callback by calling the 'prompt' method, as shown below. ```Swift func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String? , initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {} Native calls the class name, the method name, the OC Runtime, and the completionHandler method. EvaluateJavaScript: evaluateJavaScript: evaluateJavaScript: evaluateJavaScript: evaluateJavaScript: evaluateJavaScript: evaluateJavaScript: evaluateJavaScript: evaluateJavaScript: evaluateJavaScript: evaluateJavaScript Now you need to call the global callback to write the call 'JS' and tell it the result.Copy the code

Here is the overall flow chart:

conclusion

Above we analyzed the way to achieve, nothing more than using the system to provide communication ability with JS, and then with the help of the dynamic runtime to complete, although the appearance looks mysterious, but after reading the source code, will find that it is actually very simple. All the above is the original work, if there are suggestions and proposals, might as well leave a message below, I hope to be helpful to some friends.