Interaction between wkwebview and H5 page in IOS

Time:2022-5-26

iOSAnd are often needed in developmentWKWebviewThe most common way to deal with people is with themWKWebviewMediumH5Interaction between pages,H5Page is throughJavaScriptandiOSFor interaction, this article exploresJavaScriptandSwiftInteraction between.

H5 page embedding

First, let’s create a new oneHTMLFormat and name itindex.htmlIts code is as follows:

<!DOCTYPE html>
<html>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1"/>
        <style>
            .switch { position: relative; display: inline-block; width: 60px; height: 34px; }
            .switch input { opacity: 0; width: 0; height: 0; }
            label.switch { outline: none; }
            .slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; -webkit-transition: .4s; transition: .4s; outline: none; }
            .slider:before { position: absolute; content: ""; height: 26px; width: 26px; left: 4px; bottom: 4px; background-color: white; -webkit-transition: .4s; transition: .4s; }
            input:checked + .slider { background-color: #2196F3; }
            input:focus + .slider { box-shadow: 0 0 1px #2196F3; }
            input:checked + .slider:before { -webkit-transform: translateX(26px); -ms-transform: translateX(26px); transform: translateX(26px); }
            .slider.round { border-radius: 34px; }
            .slider.round:before { border-radius: 50%; }
        </style>
    </head>
    <body>
        <h2>Toggle Switch is off</h2>
        <label>
            <input type="checkbox" name="myCheckbox">
            <span></span>
        </label>
    </body>
</html>

thisH5The content of the page is very simple, alabelAnd onetoggle switch, next we areiOSMonitor in the interfacetoggle switchChange and synchronize withH5Interactive updatelabelValue of.

Interaction between wkwebview and H5 page in IOS

WKWebview

utilizeWKWebviewLoad the created aboveHTMLFile:

import UIKit
import WebKit
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(webView)
        NSLayoutConstraint.activate([
            webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            webView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            webView.bottomAnchor.constraint(equalTo: view.layoutMarginsGuide.bottomAnchor),
            webView.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor)
        ])
        if let url = Bundle.main.url(forResource: "index", withExtension: "html") {
            webView.loadFileURL(url, allowingReadAccessTo: url.deletingLastPathComponent())
        }
    }
    private lazy var webView: WKWebView = {
        let webView = WKWebView()
        webView.translatesAutoresizingMaskIntoConstraints = false
        return webView
    }()
}

message handel

becauseH5Page is usedWKWebviewLoaded,WKWebviewRelying onUIViewControllerofSwiftacceptJavaScriptThe message is throughWKScriptMessageHandlerThis protocol is implemented. This protocol provides a method to acceptJavaScriptSo here we letUIViewControllercomply withWKScriptMessageHandlerProtocol and implement a necessary method:

extension ViewController: WKScriptMessageHandler{
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        guard let dict = message.body as? [String : AnyObject] else {
            return
        }

        print(dict)
    }
}

Here assumeJavaScriptThe message sent isDicAnd simply print. The above agreement just makesUIViewControllerUnilateral acceptableJavaScriptNews, internalWKWebviewI don’t knowUIViewControllerThe simple understanding of the existence of this role is acceptable
WKWebviewThousands of news, how do I know it’s youUIViewController?For this purpose, it is necessary to adoptWKUserContentControllerThis bridge tellsWKWebview, there’s oneUIViewControllerPreparing to acceptJavaScriptThe message sent out is presented here in EnglishWKUserContentControllerMay be more appropriate:

A WKUserContentController object provides a way for JavaScript to post messages to a web view. The user content controller associated with a web view is specified by its web view configuration.

on topAutoLayoutAdd the following after the constraint:

let contentController = self.webView.configuration.userContentController
contentController.add(self, name: "toggleMessageHandler")

JavaScript send message:

Put the following paragraphJavaScriptPut code intoHTMLDocument</body>Above the label:

<script>
    var _selector = document.querySelector('input[name=myCheckbox]');
    _selector.addEventListener('change', function(event) {
        var message = (_selector.checked) ? "Toggle Switch is on" : "Toggle Switch is off";
        if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.toggleMessageHandler) {
            window.webkit.messageHandlers.toggleMessageHandler.postMessage({
                "message": message
            });
        }
    });
</script>

aboveJavaScriptCode whentoggle switchOpen towebkitsend out"Toggle Switch is on"Message, broadcast when closed"Toggle Switch is off"News.

After running the project, clickToggle SwitchThere will be a corresponding message output on the console after!

Injecting JavaScript

The above example is lucky to have itHTMLSource code, and it is written insideJavaScriptBut there is no interactive code in most cases in actual developmentHTMLSource code, ifSwiftWant to be withHTMLPage interaction can takeInjecting JavaScriptIn short, the form ofSwiftInject a sectionJavaScriptCode toWKWebviewLoadedHTMLThe interaction between the two pages.

Comment outindex.htmlAbout in the documentJavaScriptThat code, and thenViewControllerincontentController.add(self, name: "toggleMessageHandler")Add the following code below:

let js = """
    var _selector = document.querySelector('input[name=myCheckbox]');
    _selector.addEventListener('change', function(event) {
        var message = (_selector.checked) ? "Toggle Switch is on" : "Toggle Switch is off";
        if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.toggleMessageHandler) {
            window.webkit.messageHandlers.toggleMessageHandler.postMessage({
                "message": message
            });
        }
    });
"""
let script = WKUserScript(source: js, injectionTime: .atDocumentEnd, forMainFrameOnly: false)
contentController.addUserScript(script)

When running the project, you will find that the printed results are the same as before.

Evaluating JavaScript

adoptInjecting JavaScriptCan letJavaScriptSend message toSwift, and throughEvaluating JavaScriptCan letSwiftSend message toJavaScript

to updateuserContentController(_: didReceive:)The codes in are as follows:

guard let message = dict["message"] else {
    return
}
let script = "document.getElementById('value').innerText = \"\(message)\""
webView.evaluateJavaScript(script) { (result, error) in
    if let result = result {
        print("Label is updated with message: \(result)")
    } else if let error = error {
        print("An error occurred: \(error)")
    }
}

First getJavaScriptSend the message and use itscriptTo show thatJavaScriptto updateHTMLinlabelValue of, usingSwiftinWKWebViewofEvaluating JavaScriptLetJavaScriptExecute this code immediately to achieve the updateHTMLThe purpose of the text.

Interaction between wkwebview and H5 page in IOS

summary

In this article, we have seen how to implement itWKWebViewAnd the page it loads. Using this, we can use the events on the web page to trigger the actions on the application, and we can also update the loaded web page according to our information on the application.

Recommended Today

Ubuntu offline installation software

preface Test environment for Ubuntu 20.04 lts server Based on this article:https://stackoverflow.com/que… Online download download PACKAGES=”smbclient cifs-utils” apt download $(apt depends –recurse –no-recommends –no-suggests \ –no-conflicts –no-breaks –no-replaces –no-enhances \ –no-pre-depends ${PACKAGES} | grep “^\w”) pack tar -czvf smb.tar.gz ./smb/ Offline installation decompression tar -xzvf smb.tar.gz install sudo dpkg -i *.deb This article comes fromqbit […]