本文为『移动前线』群在3月24日的分享总结整理而成,转载请注明来自『移动开发前线』公众号。
bang,腾讯iOS高级工程师,开源项目JSPatch作者。目前在腾讯做微信读书iOS端。
先介绍一下 JSPatch (https://github.com/bang590/JSPatch),JSPatch 是 iOS App 动态更新库,引入后即可以用 JS 调用和替换原生任意方法,普遍用于动态下发脚本实时修复线上 Bug,目前微信微博百度地图美团等 1200 个以上 App 已接入使用。部分接入APP列表:http://using.jspatch.org
JSPatch 在还没投入使用时就就在 github 开源,因为开源社区的推动和帮助才会有今天较完善的版本和广泛的使用。目前在 Github 上有4k+ star,25位社区成员贡献过代码,算是较活跃的开源项目。
回顾起来,对 JSPatch 这个项目来说,能推动起来主要有三点: 有用 , 完善 , 推广 。
对于一个给别人使用的开源项目来说,项目有没有用自然是最重要的,有用的意思包括:1.是否有需求 2.项目是否很好地满足了需求。
对 JSPatch 来说这两点都是符合的,第1点,iOS App发展到今天,越来越多的 App 需要动态部署技术,无需等待周期不定的苹果审核,实时修复线上bug,对线上产品有更多控制力,对很多 App 开发都很有诱惑力。第2点,初期的 JSPatch 已经基本能满足这个需求。
满足了这两点,就可以开始做推广。
一般开源项目的推广会两个方式,一是线上文章,二是线下分享。我主要的方式是通过文章,我觉得一篇文章能触达的用户会比线下分享多很多,当然线下分享也很值得做,只是之前一直没精力,接下来会尝试。
文章最好不是单纯介绍这个开源项目,而是让看了的人即使不用你的开源库,也觉得有收获的技术文章。对于 JSPatch 项目来说会有一些黑魔法和脑洞,所以写了一些 JSPatch 原理解析文章,即使不使用 JSPatch 的人,相信也可以从文章中得到一些收获,这样才会获得传播。
对于其他开源项目,如果原理解析不好写,也可以挖掘一些点,回想做这个项目的思路,例如按类似 [ 面临的问题 - 业界解决方案 - 他们的缺陷 - 我的项目的优势 - 实现 ] 这样的思路去写,也会对人有所帮助。我们团队的几个开源项目也写了这样的文章:wereadteam.github.io。
如果有活跃的个人微博/公众号账号,推广上会方便很多,但这不是必须的,技术圈很简单,只要有料就能传播,质量压倒一切。
线上的推广除了文章还有其他形式,例如视频教学,在线直播,微信群分享之类,还没成为主流,有时间会尝试一下。现在就在尝试微信群分享:)
当项目初步推广起来后,越来越多的人使用,就会碰到越来越多的问题,也就会促使项目不断进行完善。开源项目的完善改进不止是代码,对 JSPatch 来说分成很多部分:
有用/推广/完善这三点实际上会形成一个正循环:有用 + 推广 -> 多人用 -> 踩坑 -> 完善(填坑 动力) -> 更好用 -> 更多人用 -> …. 可以说 JSPatch 就是这样运作起来的。
此外,对于 JSPatch 这个项目,我有一些个人理念,用乔布斯的话来说就是:保持精巧,保持好用。
JSPatch 通过几个月的迭代,增加了不少功能,但到现在仍然保持十分小巧的身型,只有三个文件,1600 行 OC 和 90 行 JS 代码,做到这样其实是需要一点删繁去简的心思和理念支撑的。
保持好用方面,除了上面说的满足需求,完善功能,还包括使用起来的体验。对给外部使用的接口我会再三思考,尽量做好。新功能的添加不会影响旧接口,甚至功能也要让位接口,例如要支持给类添加任意参数类型的方法,最简单的是在defineClass接口把这些信息传过去,但这破坏了原有接口,也让这个接口变得很别扭,所以一直没支持,直到有人想出优雅的解决方法“defineProtocol”。接口也要尽量做到好用,例如 defineProtocol 接口不会让使用者传入晦涩的“typeEncode”,而是直接传类型名,在引擎内部做一次转换。
在自己做的新功能,以及 merge 贡献者的 PR 时,都会根据这个理念再三考虑。这样做的好处是让人感觉使用成本低,也就更多人使用,更早进入上面说的循环。一直希望 JSPatch 可以给人一种“核弹头”的感觉,小巧的体积蕴藏巨大的能量。
再说一下 jspatch.com 平台,这个平台提供了 JSPatch 脚本后台托管,版本管理,加解密,灰度条件下发等功能,从开源项目到提供服务平台,思路是很自然的,我想把 hotfix 做到最好,让 JSPatch 使用成本进一步降低,那做一个平台提供这些使用时必不可少的功能是自然的思路,能力范围内能做到就尝试做了。
这个平台接入的 APP 需要不断询问后台是否有脚本更新,接入的人多了后服务器开销成本高,所以一直用内测邀请的方式控制人数,最近为了开放注册做了超出免费额度后收费,这还只是个尝试,最主要的还是推广 JSPatch 的使用,使用的人数多了以后再探索进一步发展。
最后再说下两个问题:苹果审核风险和大公司开源竞争。
JSPatch 有人一直担心审核风险的问题,虽然审核文档上写着下发 JS 可执行代码是可以接受的。但实际上苹果审核很微妙,有经验的人都知道它的审核规则很难捉摸,不同时刻都不一样,有时候人品占据因素更大。
实际上要 APP 完全不能动态化是不可能的,只要能连接后台,一个后台标识下发就能开启和关闭功能,苹果根本不知道,大量 APP 都是这样做的。即使没有 JSPatch,因为OC runtime,APP也可以根据后台下发的字符串做到动态修改任意方法,只是麻烦点。所以苹果对这块是没有办法的,审核规则也很难制定,而 JSPatch 本身主要是用来修复 bug,提高APP质量,情理上说苹果是不会拒绝的。
按我的猜测,苹果会对那些看起来“图谋不轨”的APP会重点关注动态下发这块,像提供视频下载功能,赚钱游戏,积分墙,外挂之类的APP,他们会在审核通过后下发标识或脚本修改功能,这些接入 JSPatch 可能会有风险,而看起来意图正常的APP就不会特别关注。
这是我对苹果善意的猜测,实际上现在大量 APP 接入 JSPatch,也只听说过一例被拒绝。如果跟我想的不一样,苹果要封杀 JSPatch,实际上也是封杀不了的,因为 JSPatch 没有使用私有API,他最多只能通过扫描关键字检测,只需要把关键字改了就没事了。
关于大公司竞争,川哥提了个问题:如何在大公司统治的开源环境中生存壮大?Facebook、Google出的开源项目都会受到追捧,人们也会本能的相信他们多一些,这样和他们有竞争性的开源项目的处境就很不利。如果 Facebook 出了一个类似 JSPatch 的开源项目,会如何应对?
确实人们对大公司出的开源项目信任度会高一些,但这种优势只在大型框架上,大型框架的使用成本很高,需要很多社区生态支持,特别是像React Native这种类型的项目,没有社区生态支持是搞不了的,个人项目很难做到,这点大公司有优势。而一些解决特定小问题,小而美,使用成本低的开源项目,个人也可以做得很好,大公司并没有很大优势。
开源项目是要有人用才能生长起来的,而个人做大型开源框架的问题就是初期没人使用,也就生长不起来。但小而美使用成本低的项目,只要做到前面说的几个点,就可以慢慢让更多人用起来,生长起来,而且小项目关键点少,在这块已经有很完善的解决方案的情况下,除非有重大突破,否则大公司再做一个一样的已经没什么意义了,开源项目毕竟不是创业产品,大公司不会恶意竞争。典型的案例是 jQuery 和 AFNetworking。
所以开源项目应对大公司竞争的方法就是尽快让项目成长起来,也就回到前面说的几点:有用(+使用成本低)->推广->完善。
A:没有那么长的远景目标哈,JSPatch目前短期发展目标分两个,一是继续完善修复 bug 功能,完善 JSPatch.com 平台,服务更多 APP,二是完善 JSPatch 周边设施和解决一些性能问题,让 JSPatch 可以很好地胜任动态添加功能模块。
A:会集中处理issue,遇到文档有的问题就贴个链接后直接close,也不会占用很多精力。
A:删不了。大的bug方面死锁和webview失效那个可能算吧,http://blog.cnbang.net/tech/3038/ 这篇文章有记录。
A:目前修bug的话可以直接写JS,也可以写OC代码后用 JSPatchConvertor (https://github.com/bang590/JSPatchConvertor ) 工具转成 JS。支持通过safari断点调试(https://github.com/bang590/JSPatch/wiki/JS-断点调试 )
A:因为 JSPatch 原理是runtime调用,调用和替换方法时涉及字符串处理,通过字符串查找相应Selector IMP去调用,以及处理参数类型,这个过程会比原生直接调方法慢很多。评估方式一是写大量调用对比耗时,二是做一个实际复杂度不一的 tableView 跟 OC 原生对比 fps,这个还没做。
A:JSPatch的竞品是 waxPatch,目前由阿里维护,手Q也在用。热修复我能提供的只是平台,各公司 APP 出现问题都会有原班程序员去写脚本修复,目前我觉得这个需求还没达到能创业的程度;
A:最开始我在捣鼓 JSPatch 时还不知道有 wax,后来知道了,但当时它年久失修,好几年没更新,官方版连block/arm64都不支持,需要另外去找其他人的实现,用起来会有挺多坑,另外 iOS 自带JS引擎,JS 语言也更流行,能用 JS 写是更好的。
A:安全问题当时写了篇文章(http://blog.cnbang.net/tech/2879/ ),应该说得比较清楚了。
A:是自己写的,英文不好所以一直没更新,英文真是个硬伤,如果一些JSPatch相关文章能用英语写一遍的话在国外应该会更多人用。
A:安卓版本的 patch 现在似乎已经有几个很完善解决方案了,就不再造轮子了。
A:文档有的,需要 swift 类继承自 NSObject,私有成员用 dynamic 才行。
A:完全用 JSPatch 写项目是没必要,如果是说完全用JSPatch添加功能的话,目前可能会遇到两个问题:1.开发效率,没有代码补全功能写起来比较慢 2.运行效率,像复杂 tableView 滚动这类可能会看得出性能低。接下来会尝试解决这两个问题。
感谢徐川对本文的审校。
给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ,@丁晓昀),微信(微信号: InfoQChina )关注我们。