本文为『移动前线』群在 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 来说分成很多部分:
- 核心代码。这自然是最重要的部分,修 bug 填坑,完善功能,必不可少。
- 文档。平时开发 App 不会写文档,但开源项目一定要有文档,而且文档越全面越好,JSPatch 撰写了大量文档,包括每个新功能都会有文档描述。
- 测试用例。测试用例保证项目健壮性,让项目靠谱用起来放心,JSPatch 对大部分功能都写了测试用例。
- 社区。人们使用开源项目最担心的是使用过程有什么问题没人解答,查不到资料。丰富的文档可以部分解决这个问题,此外还需要完善社区支持,包括 github issue 支持,stackoverflow 问答,交流群等,对于扩展性高的开源项目最理想的是做出一个生态环境,像 React JQuery 这类。JSPatch 在这方面只做了 github issue 和 QQ 群交流支持,继续完善中。
- 周边。对于 JSPatch 这样的项目还会有一些周边扩展和工具的完善,JSPatch 提供了像脚本加密下载、多文件 include、回退脚本这些周边功能,以及 JSPatch Convertor 这样的工具。
有用 / 推广 / 完善这三点实际上会形成一个正循环:有用 + 推广 -> 多人用 -> 踩坑 -> 完善 (填坑 动力) -> 更好用 -> 更多人用 -> …. 可以说 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。
所以开源项目应对大公司竞争的方法就是尽快让项目成长起来,也就回到前面说的几点:有用 (+ 使用成本低)-> 推广 -> 完善。
QA 环节
Q:方便说说你们远景目标么?是打算发展成大平台盈利?
A:没有那么长的远景目标哈,JSPatch 目前短期发展目标分两个,一是继续完善修复 bug 功能,完善 JSPatch.com 平台,服务更多 APP,二是完善 JSPatch 周边设施和解决一些性能问题,让 JSPatch 可以很好地胜任动态添加功能模块。
Q:对 issue 里面不看文档就问的问题怎么看?是否占用了很多精力?
A:会集中处理 issue,遇到文档有的问题就贴个链接后直接 close,也不会占用很多精力。
Q:JSPatch 目前是否具备增加或者删除一个.h .m 文件?在使用过程中你们有没有遇到什么大的 bug 可以跟我们分享下吗?
A:删不了。大的 bug 方面死锁和 webview 失效那个可能算吧, http://blog.cnbang.net/tech/3038/ 这篇文章有记录。
Q:之前没了解过,开发周期相对原生态需要来说是怎样的?也就是说开发效率怎样?是否支持 debug?
A:目前修 bug 的话可以直接写 JS,也可以写 OC 代码后用 JSPatchConvertor ( https://github.com/bang590/JSPatchConvertor ) 工具转成 JS。支持通过 safari 断点调试 ( https://github.com/bang590/JSPatch/wiki/JS- 断点调试 )
Q:请问 JSPatch 对性能的影响有多大,怎么评估的?
A:因为 JSPatch 原理是 runtime 调用,调用和替换方法时涉及字符串处理,通过字符串查找相应 Selector IMP 去调用,以及处理参数类型,这个过程会比原生直接调方法慢很多。评估方式一是写大量调用对比耗时,二是做一个实际复杂度不一的 tableView 跟 OC 原生对比 fps,这个还没做。
Q:JSPatch 有什么竞品吗?为什么不考虑创业提供专业的热修复服务?
A:JSPatch 的竞品是 waxPatch,目前由阿里维护,手 Q 也在用。热修复我能提供的只是平台,各公司 APP 出现问题都会有原班程序员去写脚本修复,目前我觉得这个需求还没达到能创业的程度 ;
Q:最开始需要动态修复方案的时候有没有考虑过直接用 wax,为什么要选择做一个新的?
A:最开始我在捣鼓 JSPatch 时还不知道有 wax,后来知道了,但当时它年久失修,好几年没更新,官方版连 block/arm64 都不支持,需要另外去找其他人的实现,用起来会有挺多坑,另外 iOS 自带 JS 引擎,JS 语言也更流行,能用 JS 写是更好的。
Q:JSPatch 的安全性,是怎么做的?
A:安全问题当时写了篇文章 ( http://blog.cnbang.net/tech/2879/ ),应该说得比较清楚了。
Q:JSPatch 的英文文档是你自己写的么?
A:是自己写的,英文不好所以一直没更新,英文真是个硬伤,如果一些 JSPatch 相关文章能用英语写一遍的话在国外应该会更多人用。
Q:有没有考虑做安卓版本的 patch?
A:安卓版本的 patch 现在似乎已经有几个很完善解决方案了,就不再造轮子了。
Q:JSPatch 可以调用 swift 的方法吗?
A:文档有的,需要 swift 类继承自 NSObject,私有成员用 dynamic 才行。
Q:请问建议完全用 JSPatch 写项目吗?有多大风险?
A:完全用 JSPatch 写项目是没必要,如果是说完全用 JSPatch 添加功能的话,目前可能会遇到两个问题:1. 开发效率,没有代码补全功能写起来比较慢 2. 运行效率,像复杂 tableView 滚动这类可能会看得出性能低。接下来会尝试解决这两个问题。
感谢徐川对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ , @丁晓昀),微信(微信号: InfoQChina )关注我们。
评论