Rollout 打算实现 Swift iOS 应用的在线更新

  • Sergio De Simone
  • 王纯超

2016 年 11 月 16 日

话题:移动iOS语言 & 开发

Rollout 创建了能绕开 AppStore 评审流程的在线更新(live-update)原生 Objective-C 应用的解决方案 。它宣布该解决方案能支持 Swift 了。Rollout 把这项在线更新 Swift 应用的技术叫伪方法偷换(pseudo method-swizzling)。

Rollout 给 Objective-C 应用打补丁的机制是一项叫做方法偷换的动态编程技术。通过修改 Objective-C 运行时将方法签名关联到一个类中的某个函数的方式,开发人员能更改该方法的实现。被偷换的方法(swizzled method)会被完全替代或者被一个从 Rollout 云上下载下来的新实现简单包裹起来。Rollout 允许开发人员使用 JavaScript 定义偷换方法(swizzling method),这是这项机制与苹果的指导方针兼容的关键。苹果的指导方针只允许下载在 WebKit 或者 JavaScript Core 上运行的代码。或者,使用预定义的模板作为 Objective-C 的补丁。这些模板用来完成特定的目标,例如给方法调用添加跟踪日志、禁用方法等等。

Swift 不支持原生的方法偷换。所以正如 Rollout 的 CTO Eyal Keren 解释的,因为 Swift 没有运行时编程(runtime-programming )能力,针对 Swift 他们不得不开发出类似的东西来。简而言之,Rollout 做的就是在Swift 中间语言层(Swift Intermediate Language,SIL)给每个方法添加一个前缀来操作应用的。方法类似如下代码:


func add(a:Int, b:Int) -> Int {
if Rollout_shouldPatch(ROLLOUT_a79ee6d5a41da8daaa2fef82124dcf74) {
    let resultRollout : Int =
    Rollout_invokeReturn(Rollout_tweakData!,
        target:self,
        arguments:[a,
            b,
            origClosure: { args in return self.add(a:args[0],b:args[1]);});
    return resultRollout;

在上面的代码中,Rollout_invokeReturn 负责执行一个从 Rollout 云下载的 JavaScript 函数。如果需要,该函数可以回调初始的方法。

Rollout 能在多种情境中支持 Objective-C。尽管 Rollout 在努力改进,但相比 Rollout 对 Objective-C 的支持而言,Rollout 对 Swift 的支持仍然在起步阶段。尤其是:

  • Swift 补丁不能执行原生的 Swift 方法,除非该方法就是被打补丁的方法或者带有 @objc 的方法。它也不能创建原生的 Swift 对象。
  • 仅仅能覆盖有限类型的返回值,例如 String、Number、Optional 和所有与 Objective-C 兼容的类。
  • 不能捕获 Swift 的原生异常。
  • 仍然不支持 Swift 的一些特性,例如静态类方法、重载实例方法、struct 方法等等。

Rollout 证实,以上列举的一些限制已经实现了,当前正处于 beta 测试中。

Rollout 表明,它们的在线更新解决方案当前正用于数以千计的移动应用程序,绝对是符合苹果指导方针的正统解决方案

查看英文原文:Rollout Aims to Enable Live Updates for Swift iOS Apps


感谢冬雨对本文的审校。

给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ@丁晓昀),微信(微信号:InfoQChina)关注我们。

移动iOS语言 & 开发