【iOS】什么?不编译就可以更新代码

753 阅读2分钟
原文链接: www.jianshu.com

项目地址

github.com/xurunkang/N…

前言

对于 iOS 的中大型项目来说,编译耗时的问题永远是一个痛点。缓解的方案有许多:ccache 等缓存方案 / 优化 Xcode 配置 / 加钱堆硬件。
这些方案的出发点都是基础优化编译耗时来解决的,哪有没有一个办法可以做到不编译就执行修改后的代码呢?
基于 Objective-C 的动态特性,是完全可以做到这一点的,这也是各种热修复框架的支撑原理之一。那么如果需要做到不编译就执行修改后的代码,我们可以这样做:获取本地修改后代码 -> 转 JavaScript 或 Lua -> 模拟器执行修改后的脚本

大致思路

获取本地修改代码

这里也有许多方法,可以手动复制,也可以自动获取。这里我是选择利用 Xcode Editor Extension 来获取到你选中的修改代码的。

Objective-C 转 JavaScript

由于整个流程我是基于 JSPatch 来开发的,所以是需要转为 JS 的脚本。这里我是写了个 node.js 的脚本来实现,转换算法是利用 github.com/bang590/JSP… 中的开源代码。

模拟器执行修改后的脚本

由于已经有 JSPatch 完整的框架做支撑,这里只需要利用其中的方法 -[JPEngine evaluateScriptWithPath:] 去执行修改后的脚本即可。

具体实现流程图

流程图
流程图
  1. 项目和本地 Node 服务器建立 Socket 连接
  2. 修改 test 代码
  3. 利用 Xcode Editor Extension 获取修改的代码
  4. 将修改代码发送到本地 Node 服务器
  5. 执行 Node 脚本将 OC 转 JS
  6. 执行 Node 脚本将 JS 写入到本地文件
  7. 利用 Socket 通知项目更新
  8. 项目执行 -[JPEngine evaluateScriptWithPath:] 函数注入 JS 代码
  9. 重新执行 test 代码

(我是从零开始的啊,为什么markdown就要转为1呢~)

这里使用 Node.js 有两个原因:Xcode Editor Extension 不支持直接执行沙盒外脚本(所以是通过 Extension 向 Node 服务器发送 Http 请求来传递修改的代码),而且和 iOS 模拟器进行进程通信比较麻烦(尝试了 CFNotification 等几种方法都不行,所以使用 Node 搭建 Socket 服务器达到进程通信)。

视频演示

ocnnxadky.bkt.clouddn.com/KK_NO_COMPI…

缺陷

自动转换脚本目前不支持如下类型:

Macro / constant variable / Enum
C function calling
GCD functions
Pointer / Struct
Getting / Setting private variable