Skip to content

可定制化

iMoeNya edited this page Apr 23, 2024 · 1 revision

DSBridge-Swift 的 DSBridge.WebView 中几乎没有逻辑,逻辑被移放到了作为中枢的拱心石 Keystone 中。

拱心石(英语:Keystone),是砖石拱门顶上的楔形石头以及圆形石头。这些石块是施工过程中最后一块安放的石头,它主要能将所有的石头固定在位置上。 – 维基百科

这是使用 DSBridge-Swift 时,JavaScript 调用 Native 的同步方法的过程:

接下来,我们将介绍其中各个环节的可定制性,你会了解到 DSBridge-Swift 是如何实践开闭原则的。

解析来自 JavaScript 的调用

你可以修改 KeystonejsonSerializer 和/或 methodResolver,这两个对象负责将来自 JavaScript 的调用转化为 IncomingInvocation(DSBridge-Swift 对于来自 JS 的调用的封装)。

想用 SwiftyJSON 或者 HandyJSON?想修改传参格式?没问题,修改 jsonSerializer 就行:

import class DSBridge.Keystone
// ...
(webView.keystone as! Keystone).jsonSerializer = MyJSONSerializer()
// ...

还有比如 DSBridge-Swift 仅在开发环境中打印 JSON 序列化报错的详情;生产环境中,具体的对象或 JSON 字符串会被替换为*hashed*或者一个空对象。如果你希望改变这一行为,你可以自己定义错误类型,而不使用 DSBridge.Error.JSON 之下的那些。

methodResolver 更为简单,它只是从诸如 street.getName 的字符串中提取出命名空间和方法名。

(webView.keystone as! Keystone).methodResolver = MyMethodResolver()

派发 Invocation

在将被封装为 Invocation 后,调用来到了 Dispatcher。

Keystone.invocationDispatcher 负责管理所有你注册的 Interface,并负责将 IncomingInvocation 派发给它的目标 Interface

你可以替换它,提供你自己的实现:

(webView.keystone as! Keystone).invocationDispatcher = MyInvocationDispatcher()

执行 JavaScript

为了解释如何自定义 JavaScript 执行,这是 JavaScript 异步调用的过程。

调用抵达 Dispatcher 之前的过程与同步方法无异。当 Dispatcher 接收到异步调用时,它会立刻返回一个空的响应,以使网页可以继续运行。至此,同步的返回链条已经断开了。

与此同时,它把调用派发给 Interface。由于同步返回的通道已经关闭,DSBridge-Swift 将通过执行 JavaScript 的方式发送响应数据:

JavaScriptEvaluator 负责管理所有发向 JavaScript 的消息,仿照 DSBridge-iOS,它每 50ms 才执行一次 JavaScript 脚本,避免执行过于频繁,被 iOS “丢包”。原来的 DSBridge-iOS 只针对回调(响应来自 JS 的异步调用)做了优化,Native 主动调用仍然会出现丢包;DSBridge-Swift 则对于 Native 的主动调用也做了等待队列。

如果你需要做进一步的优化,或者不想要这样的优化,还原本来的体验,你完全可以将 Keystone.javaScriptEvaluator 替换掉。

拱心石

有了上面这样的可扩展性,你甚至可以修改 JS 端的代码,而无需修改 DSBridge-Swift 的源码。

在这之上,你甚至可以重新定义自己的拱心石,完全替换掉从接收来自 JS 的原始字符串之后的所有逻辑。这需要你实现 DSBridge.KeystoneProtocl,你可以利用或舍弃 DSBridge-Swift 中的现成实现,打造一个完全不同的 Bridge。