从Swift到Javascript然后返回

调用函数和评估脚本

所有这一切真正酷的是,您拥有支持WebKit(iOS和MacOS的Safari)的JavaScript引擎。 该增加一点时间了。 我喜欢为iOS开发,但我也花了很多时间为Node.js和网络开发。 我经常使用JavaScript库来减少必须编写的代码量,因为那里有比我更聪明的开发人员,他们已经进行了一些繁重的工作并创建了一些非常有用的东西。 因此,下一步是了解如何在代码中包含和使用现有的JavaScript库。

对于我们的示例,我将使用Moment.js来简化一些日期时间操作。 顺便说一句,我在所有实验中都使用了Playground。 如果您想继续,请使用iOS目标创建一个新的Playground文件。 从那里,您需要Moment.js库的JavaScript代码,该库是我使用Bower在本地安装的。 接下来,我将moment dir复制到Playground的Resources文件夹中。 如果您对此有疑问,可以参考我的其他一篇有关使用Playgrounds的文章。

接下来,我们需要找到moment.js文件的路径,将文件内容复制到String中,然后将其注入到JSContext中 。 请参阅下文,了解如何实现此目的。

这里重要的一点是,如果您调用JSContext的validateScript ()方法,则您正在执行的代码(在我们的示例中)将整个moment.js库添加为该特定JSContext的全局对象。 以后添加的任何脚本或JavaScript对象都可以使用moment.js的所有功能。

好吧,至少听起来不错。 事实是,这取决于您注入JSContext的脚本的内容。 为了使Moment.js库正常工作,我们需要通过另一个评估脚本调用来调用它的构造函数和格式函数。 完成此操作后,我们可以使用JSContextobjectForKeyedSubscript方法获得对moment.js库的引用,该方法将为我们提供初始化的moment.js对象。 有关如何调用方法或使用参数调用构造函数的一些示例,请参见上面的示例,这些示例在幕后使JavaScript发生了正确的事情。 一切都很强大。

扩展示例

继续前进,我想提供一个更深入的示例,让您考虑在自己的代码中实际使用它的可能性。 我们将创建一个用于显示联系人的小应用程序。 每次执行时,我们仅使用JavaScript库Faker代替真正的联系人,为我们提供新的联系人详细信息。 我们的示例将使我们能够在Swift中为联系人对象建模,并在Swift中创建可以在JavaScript中执行的函数。 我们还需要从具有“伪造”联系方式的JavaScript方面获取数据。 最后,我们将使用WKWebView实例在Playground的视图中显示联系人。

第一步是创建一个联系人对象和一个JSExports协议,该协议概述了我们想要向JavaScript公开的内容。 之后,我们需要使用JSContextsetObject方法来使我们的联系人对象可以在JavaScript中访问。

下一步是创建可以在JavaScript中执行的Swift函数。 我们需要使用@convention(block)语法将Swift闭包转换为一个块,该块将成为具有相同参数和返回值的JavaScript函数。 我们再次调用JSContextsetObject方法将方法传递给JavaScript。 但是,这一次,我们需要使用unsafeBitCast方法将Swift闭包转换为AnyObject类型,以使JavaScript能够正确处理。

我们的下一系列操作旨在向您展示如何从JavaScript调用和使用contact对象以及我们的createContact函数。 您将创建一个contact.js脚本并将其添加到Playground的Resources文件夹中。 我们的脚本将具有一个使用Faker.js库创建虚假联系人的函数。 目的是调用该方法以将新联系人添加到Playground中的视图中,并返回创建的联系人以进行进一步检查。

上面的代码为我们要向JavaScript公开的另一个对象创建了JSExports协议和类。 我们还将这个新类添加到我们的JSContext中,以便可以通过JavaScript对其进行访问。 另外,我们创建Swift方法将新的联系人对象添加到我们在Playground中可以看到的视图中。

接下来,我们需要将Faker.js库添加到我们的JavaScript环境中。 我们遵循用于添加Moment.js的相同模式。 我们还将我们的contact.js文件添加到我们的环境中,该文件将createFakeContact()方法添加到我们的全局范围中。 然后,我们在本机端获取对createFakeContact()方法的引用并执行它。 我意识到JavaScript与Swift中发生了很多来回的变化,但坦率地说,这是关键。 我希望您看到您可以轻松地来回传递对象并从任一侧执行方法。

我们需要做的最后几件事是添加page.html文件,该文件由WKWebView在我们的ContactDrawable类中加载。

为了显示我们的联系人,我创建了一个UIView并将其分配给XCPlaygroundPage.currentPage.liveView 。 执行Playground将显示一个简单列表,其中包含随机创建的“伪造”联系方式。

包起来

操场上会显示一个视图,其中的联系方式在每次运行时都会更改。 稍加想象,您就可以修改该示例,以制作可通过JavaScript创建和控制的本机UI对象。 另一种可能性是使用从服务器下载的脚本扩展应用程序,以实例化Swift类以执行本机任务。

简要地说,我还写了一篇文章,说明为什么创建本地应用程序可能是大多数移动开发工作中最好的方法。 阅读并参与讨论!

您的混合应用程序将杀死您
如果您的公司仅开发混合应用程序,那么最终您将蒙受损失。 这只是时间问题。 混合手机…medium.com

希望您对此帖子感兴趣。 如果您喜欢它,推荐并喜欢它!