swift – 与WKWebView进行JavaScript同步本地通信

前端之家收集整理的这篇文章主要介绍了swift – 与WKWebView进行JavaScript同步本地通信前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
使用WKWebView可以在JavaScript和Swift / Obj-C本机代码之间进行同步通信吗?

这些是我尝试过的并且失败的方法.

方法1:使用脚本处理程序

WKWebView接收JS消息的新方式是使用委托方法userContentController:didReceiveScriptMessage:从JS调用的是window.webkit.messageHandlers.myMsgHandler.postMessage(“生命的本机代码是什么意思?”)
这种方法的问题是在执行本机委托方法时,JS执行不被阻止,所以我们不能立即调用webView.evaluateJavaScript(“something = 42”,completionHandler:nil)来返回值.

示例(JavaScript)

var something;
function getSomething() {
    window.webkit.messageHandlers.myMsgHandler.postMessage("What's the meaning of life,native code?"); // Execution NOT blocking here :(
    return something;
}
getSomething();    // Returns undefined

示例(Swift)

func userContentController(userContentController: WKUserContentController,didReceiveScriptMessage message: WKScriptMessage) {
    webView.evaluateJavaScript("something = 42",completionHandler: nil)
}

方法2:使用自定义URL方案

在JS中,使用window.location =“js:// webView?hello = world”进行重定向调用本机WKNavigationDelegate方法,可以提取URL查询参数.但是,与UIWebView不同,委托方法不阻止JS执行,因此立即调用evaluateJavaScript将值传回给JS也不起作用.

示例(JavaScript)

var something;
function getSomething() {
    window.location = "js://webView?question=meaning" // Execution NOT blocking here either :(
    return something;
}
getSomething(); // Returns undefined

示例(Swift)

func webView(webView: WKWebView,decidePolicyForNavigationAction navigationAction: WKNavigationAction,decisionHandler decisionHandler: (WKNavigationActionPolicy) -> Void) {
    webView.evaluateJavaScript("something = 42",completionHandler: nil)
    decisionHandler(WKNavigationActionPolicy.Allow)
}

方法3:使用自定义URL方案和IFRAME

这种方法仅在分配window.location的方式上有所不同.而不是直接分配它,而是使用空的iframe的src属性.

示例(JavaScript)

var something;
function getSomething() {
    var iframe = document.createElement("IFRAME");
    iframe.setAttribute("src","js://webView?hello=world");
    document.documentElement.appendChild(iframe);  // Execution NOT blocking here either :(
    iframe.parentNode.removeChild(iframe);
    iframe = null;
    return something;
}
getSomething();

然而,这不是一个解决方案,它调用方法2相同的本机方法,它不是同步的.

附录:如何用旧的UIWebView实现这一点

示例(JavaScript)

var something;
function getSomething() {
    // window.location = "js://webView?question=meaning" // Execution is NOT blocking if you use this.

    // Execution IS BLOCKING if you use this.
    var iframe = document.createElement("IFRAME");
    iframe.setAttribute("src","js://webView?question=meaning");
    document.documentElement.appendChild(iframe);
    iframe.parentNode.removeChild(iframe);
    iframe = null;

    return something;
}
getSomething();   // Returns 42

示例(Swift)

func webView(webView: UIWebView,shouldStartLoadWithRequest request: NSURLRequest,navigationType: UIWebViewNavigationType) -> Bool {
    webView.stringByEvaluatingJavaScriptFromString("something = 42")    
}
不,由于WKWebView的多进程架构,我不相信这是可能的. WKWebView与您的应用程序运行在相同的过程中,但它会与运行在其自身进程( Introducing the Modern WebKit API)的WebKit进行通信. JavaScript代码将在WebKit进程中运行.因此,基本上你要求在两个不同的进程之间进行同步通信,这违反了他们的设计.
原文链接:https://www.f2er.com/swift/319822.html

猜你在找的Swift相关文章