在WKWebView和本机代码之间创建链接

在过去的一个月中,我一直在为对产品有一些特定要求的客户工作; 他们想要一个使用特定地图组件的应用程序,就像他们在网络应用程序中使用的组件一样。 这意味着两件事:javascript🙈并试图找出如何在本机代码和将包含地图的Web视图之间进行通信。

让我们花一些时间来概述问题。 我们在这里处理两个主要组件:用于容纳地图的WKWebView和本机用户界面。 我们希望在这些组件之间双向发送消息。 当用户与地图上的某些对象进行交互时,我们需要在本机代码中触发事件以执行操作,例如显示界面元素,或触发对新视图的选择。 我们还需要从本机代码向Webview发送消息,因此我们可以将所有繁重的工作委托给本机应用程序,以最大程度地减少javascript必须进行的计算。

对我们来说很幸运,WKWebView提供了我们需要的一切。 稍作修改,我们就可以对其进行配置,使其完全满足我们的需求! 设置Web视图是很简单的,而且有据可查,因此这里不再赘述。 您可以通过代码实例化它,也可以在Interface Builder中的视图中拖动一个并为其创建出口。 我选择了后者。

让我们使ViewController符合WKScripMessageHandler和WKNavigationDelegate:

不要忘记在viewDidLoad中将网络视图的na vigationDelegate设置为self!

好了,现在我们已经拥有了Webview设置的一部分。 稍后我们将再次讨论,但是首先,我们将深入研究一些javascript。

快速免责声明:我不是Web开发人员。 如果您是经验丰富的javascript专业人士,请避开下面的代码。

我们需要在javascript中做的就是创建一些函数来处理传入的响应,并将响应发送回Webview。 我希望您对设置index.html文件感到满意,所以我不会向您展示如何做到这一点。

现在,我们可能想做其他事情,而不仅仅是记录接收到的值,但是为了解释这个概念,这样做就可以了。 假设我们要在Web视图中保留一个人员列表,那么将从本地上下文中调用addPerson函数以将其添加到Web视图中。 可以调用sendNameToNative函数将消息发送回本机代码。 让我们添加最后一个构建块,以使一切正常工作!

我们需要在loadView函数中做一些事情,所以我们将重写它。 在这里,我们将为Web视图设置一些属性,以在调用sendNameToNative函数时侦听来自javascript的回调。

您可能需要根据设置视图的方式来摆弄这个。 您可能要做的一件事是将框架更改为等于view.frame,而另一处可能解决问题的方法是在最后一行之后添加view = webview 。 这可能会带来其他问题。

这里只剩下一件事要做,实际上是在向Webview发送消息。

这是我们难题的最后一部分; 实际将消息发送到Webview。 调用此函数使我们可以在Web视图中执行javascript。 在示例中可以看到,当我们要发送字符串时,需要在其周围添加”。 现在,我们可以在webView(_:didFinish 🙂函数中调用类似的函数来设置加载时的Webview,并在与本机用户界面交互后调用它以发送更多消息。

请记住,当您处理用户输入的属性时,您可能需要对其进行验证,以免在Web视图中执行恶意的javascript。

现在您已经确定了结构,可以开始疯狂了:

  • 实际处理响应以触发本机代码中的某些动作,例如动画或segue。
  • 添加更多处理程序以处理来自Web视图的不同响应,从而在两者之间创建紧密连接

恭喜你! 如果您正在阅读本文,那么您已经在WKWebView和应用程序的本机上下文之间创建了连接。 这提供了很多可能性,您可以根据需要进行扩展。 如果您为此创造了一些很棒的东西,请与我分享!


如果您喜欢这篇文章,请查看 我写 其他文章 如果您想保持联系,可以在 Twitter上 关注我, 或在 LinkedIn 上给我发消息 另外,如果您需要有关iOS编程的任何帮助,则可以 加入为此 目的而创建的 Discord服务器 🙂