BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

Instagram的iOS原生代码热加载技术

| 作者 Instagram工程博客 关注 0 他的粉丝 ,译者 胡红星 关注 0 他的粉丝 发布于 2018年5月11日. 估计阅读时间: 4 分钟 | GMTC大前端的下一站,PWA、Web框架、Node等最新最热的大前端话题邀你一起共同探讨。

亲爱的读者:我们最近添加了一些个人消息定制功能,您只需选择感兴趣的技术主题,即可获取重要资讯的邮件和网页通知

在Instagram和Facebook,React Native让我们能够以更快的速度推进迭代产品。在模拟器上使用⌘R快捷键就可以查看更改效果。然而使用原生代码进行开发,每次都需要重新编译、链接、安装、启动等一系列步骤才能查看更改效果。

即便是一个小项目,这样的开发流程也会让开发者感到很繁琐。在我们的项目规模上,结果就是工程师要花费大量的时间来等待电脑完成构建任务,等待的过程中又经常会切换到其他应用,从而浪费了更多的时间。

去年年底我们着手将React Native的开发体验带入Objective-C原生代码的开发中,目的是让工程师能及时看到代码更改效果。为了实现这一点,我们通过在运行时加载新代码来避免重启应用。

如何重新加载原生代码

为了重新加载原生代码,第一步需要将修改过的代码转换成正在运行的应用可以加载的动态库。这一步操作非常快,该操作以文件为单位进行:只编译有改动的文件,并链接为一个动态库。

iOS真机设备不允许应用加载其自身bundle以外的动态库。同时也不允许应用向其自身bundle写文件。因此可加载的动态库必须在应用安装时就已经存在其bundle里,因此无法在真机上加载新的动态库。

幸运的是,iOS模拟器上并没有这些限制。每个模拟器的文件系统其实就是Mac文件系统里的一个文件夹。另外,iOS模拟器中的dlopen函数不会按文件位置进行过滤,这使得无论如何都可以直接将动态库写入应用程序的bundle中。

我们在程序代码中新增了一个启动方法,该方法会在debug模式下生成一个后台任务来监听指定文件夹的内容变化。动态库创建好后会移动到指定文件夹。这会触发应用中设置好的回调,执行以下几个步骤:

  • 加载新的动态库。
  • 确定添加了哪些Objective-C类。
  • 查找这些类的原始版本。Objective-C类本身也是对象,很容易通过名字找到。
  • 使用Objective-C运行时APIs来替换这些原始类的方法实现为新的实现。这会替换类所有的方法实现,因为我们无法确定哪些方法实现有改动。
  • 将执行结果写回相同目录以便工具读取。

到这里我们的新代码已经在应用中跑起来了,下一次调用这些方法就会执行我们的新代码。当然,这只有在iOS模拟器上做开发时可用,真机和生产环境是不可行的。

构建开发体验

重新安装、重启应用来查看更改效果很慢,但简单可靠。在Xcode中按下按钮或快捷键,最终,代码的结果会显示在屏幕上。我们在我们的插件工具中做了类似的事情:在Xcode的工具栏放置了一个按钮和快捷键来触发加载新的代码。

与重启应用相比我们还有另一个优势:保持应用的当前状态。重启会重置应用回到最初的入口 - 对我们的应用来说是feeds首页。负责其他模块的工程师必须重新点击进入到自己的模块才能查看他们的修改是否正确。

然而,新的代码加载后,什么也不会发生:应用之前的状态不会受到影响。幸运的是,在Facebook上使用的声明式iOS UI框架ComponentKit具有执行即时重新布局的有用方法:+ [CKComponentDebugController reflowComponents]。使用ComponentKit构建的视图可以在新代码加载后调用该方法,来让布局代码重新执行并,并在屏幕上立即更新。结果就是,使用ComponentKit进行布局,工程师可以及时查看布局的修改。以前,工程师需要批量更新并考虑何时需要重启。 现在他们可以交互式地迭代工作。

总结

我们的工具在小组内已变得非常流行,特别是使用ComponentKit的工程师。在大型应用中,这使得工程师查看修改结果的速度提升了20倍。高性能、与现有开发工具和框架的紧密结合已经让原生代码的加载成了在Instagram和Facebook的iOS工程师平时工作流程中的重要一环。

Nate Stedman一名来自Instagram纽约的iOS工程师。

感谢覃云对本文的审校。

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我
社区评论

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT