我如何从 JS 到 Swift 通信

Posted

技术标签:

【中文标题】我如何从 JS 到 Swift 通信【英文标题】:How do I communicate from JS to Swift 【发布时间】:2017-12-18 00:00:32 【问题描述】:

我正在创建一个混合应用程序,并试图弄清楚如何将一些数据从 WKWebView 传递到本机应用程序。

这几天我一直在尝试解决这个问题,但我似乎找不到任何东西!网上关于这方面的信息似乎很少,而我所找到的一切都是相反的(Swift 到 JS,而不是 JS 到 Swift)。

我尝试过使用 URL 变量,但 Webview 必须重新加载才能让 Swift 识别它已更改。我尝试使用WKScriptMessageHandler,但找不到任何好的文档,而且看起来很复杂。

必须有一些简单的方法来实现这一点。 有什么想法吗?

我会非常感谢任何可以帮助我的人。

【问题讨论】:

【参考方案1】:

其实没那么复杂。

首先,您必须将脚本消息处理程序添加到内容控制器中。

let contentController = WKUserContentController()
contentController.add(self, name: "derp") //name is the key you want the app to listen to.

接下来您必须将内容控制器分配到配置中。

let config = WKWebViewConfiguration()
config.userContentController = contentController

那么您需要将配置分配给您的 Web 视图。

let webView = WKWebView(frame: CGRect.zero, configuration: config) //set your own frame

对于 JS 方面。

var message = 'fruit':'apple';
window.webkit.messageHandlers.derp.postMessage(message);

最后,您必须让您的视图控制器(我假设 webView 在视图控制器中)符合 WKScriptMessageHandler 协议。我已按要求将其余代码添加到示例视图控制器中。

class MyViewController: UIViewController, WKScriptMessageHandler 

    override func viewDidLoad() 

        super.viewDidLoad()

        let contentController = WKUserContentController()
        contentController.add(self, name: "derp")

        let config = WKWebViewConfiguration()
        config.userContentController = contentController

        let webView = WKWebView(frame: self.view.frame, configuration: config) //you can consider using auto layout though
        self.view.addSubview(webView)

        //load your url here 
    

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) 

        //handle script messages here
        //message.name is "derp"
        //message.body is ["fruit":"apple"]
    

【讨论】:

我是ios新手。您介意在 Swift 部分详细说明一下吗?我不确定在哪里添加脚本消息处理程序,或者在哪里分配配置。你能给我看一个完整的 viewcontroller.swift 文件吗? 一切正常。但我似乎无法解决另一个问题。在您的代码中,您创建了一个新的 WebView,然后将其添加到子视图中。但是,我已经有一个现有的 Web 视图。如何在不创建新视图的情况下将您的“配置”分配给我当前的 Web 视图?再次感谢您的帮助。 也许你可以尝试直接设置 userContentController。 webView.configuration.userContentController = contentController 出于某种原因,它仅在我创建新的 Web 视图并将其添加到子视图时才有效。但是如果我尝试将 userContentController 直接设置为现有的 webview,它就不起作用。有什么想法吗? 没关系,我想通了。就是这样... let contentController = self.webView.configuration.userContentController; contentController.add(self, name: "derp");

以上是关于我如何从 JS 到 Swift 通信的主要内容,如果未能解决你的问题,请参考以下文章

SWIFT:从定义 tableView 到 tableViewCell 的 ViewController 通信数据

node.js 和 PHP 之间如何通信?

SWIFT:将字节从 NSData 粘贴到 Struct?

JavaScript 同步原生通信到 WKWebView

在 React.js 中,我将如何设置一个简单的全局事件系统来在组件之间进行通信?

MQTT通信协议在Unity中的应用之——JS实现