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
-
Know Javascript = = =
[call]
===> NativeHow 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
-
Understand the Native = = =
[call]
===> JavascriptThe 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.