JSPatch相关内容预研

背景介绍

APP的热更新技术是一种防御编程,应用场景是:线上发现了bug,如果要发新版本修复,那么由于苹果的审核周期较长,来不急了,所以需要一种不走苹果审核流程也能解决Bug的技术手段。
bang590/JSPatch 目前已经是事实标准,有很多APP在用Who is using JSPatch?

功能简介

  • “JSPatch 可以让你用 JavaScript 书写原生 iOS APP。只需在项目引入极小的引擎,就可以使用 JavaScript 调用任何 Objective-C 的原生接口,获得脚本语言的优势:为项目动态添加模块,或替换项目原生代码动态修复 bug。”

  • 这段话说得非常清楚,是用JavaScript调用Object-C,那么对于Swift写的工程呢?只能说是部分支持,在基础用法-Swift已经有很好的说明。结合这篇文章,应该会有比较清楚的区分Swift Runtime分析:还像OC Runtime一样吗?

  • 可以使用 JSPatch Convertor 自动把 Objective-C 代码转为 JavaScript 代码。JS代码不需要和iOS客户端代码一起发布,所以这个工具离线使用,不需要整合进工程。在需要hotfix的JS文件时再用,降低写JS代码的难度。在写测试用例,或者实际使用的时候会有用,但是自动生成的代码还是要人工检查过再用比较好。

  • 语言选择Object-C,不选Swift;用Swift的话,JSPatch有时候不起作用,就没有引入的必要了。

客户端使用

  1. 初始化[JPEngine startEngine]
  2. 执行脚本[JPEngine evaluateScript:script]

需要考虑的是JS脚本如何加密,如果保证安全,如何取得,执行时机等等。这些方面,需要好好设计一下。

JS执行方式

  1. exec js directly === 直接执行JS脚本
  2. exec js file from network === 给个url,直接从网络下载JS脚本执行
  3. exec local js file === 执行本地JS文件

以上三种是官网中的例子,实际中都比较难直接用

  • 直接执行JS脚本?=== 本地知道要怎么改了,为什么不直接改掉,还绕这么一大圈?

  • 给个url,直接从网络下载JS脚本执行?=== 明文传输,被人改了怎么办?

  • 执行本地JS文件 === 还是那句话,本地知道要怎么改了,为什么不直接改掉,还绕这么一大圈?

那么实际怎么用呢?

  1. JS文件保存到服务器,JS文件内容加密

  2. JS文件通过下载通道,下载到客户端

  3. 客户端执行本地JS文件,完成bug修复

安全策略

  • JS文件传输,需要保证文件不被替换,一般用MD5

  • JS文件内容进行加密,比如AES128

版本管理

  • 后台需要知道哪个APP要打补丁?一般可以用bundleId来区分

  • 哪个版本需要打补丁?一般通过version和build两个字段可以确定

  • 后台存储就按照hotfix -> osType -> bundleId -> version ->build的目录结构进行存放

  • 补丁文件固定为patch.js,md5值事先算好,放在md5.txt中,当然文件类型可以按照实际情况自定义

  • 后台根据客户端提交的osType,bundleId,version,build等进行查找,能找到补丁文件,就说明需要热更新,否则就不需要

patch文档存储.jpg

JS文件是否要缓存?

  • 观点1:不需要缓存,热更新一般用于紧急bug,流程控制如果不是太烂,没有多少内容的,所以每次启动,去下个补丁,执行一下,用完就扔,省得麻烦。至于没网络的情况下,APP一般都不正常,热补丁本身就没有多少意义。
执行流程-无缓存.jpg
  • 观点2:需要缓存,同一份补丁只要下载一次就好,没有必要重复下载。并且,下载还有延迟,也不能保证文件一定很小。没网络的情况下,有缓存也能起到热更新的作用。
执行流程-有缓存.jpg
  • 观点3:补丁的执行不能依赖网络。执行的是缓存中的补丁文件。有网络,需要更新补丁文件,才下载更新,替换补丁文件。这个方案的问题就是第一次肯定没补丁,要先下载,下次启动再执行补丁文件。另外,网络,下载可能需要耗费比较长的时间,补丁执行太靠后,Bug可能还是会重现。所以,执行补丁和下载更新补丁应该是两个完全不同的过程。最终,这种观点被团队采纳。
    先执行,再下载;下载的文件等下次启动再用。
缓存执行.jpg
补丁文件下载.jpg

更新时机

  • 一般情况,放在didFinishLaunchingWithOptions:中,程序启动时,一次执行就好了。

  • 放在applicationDidBecomeActive:中,是为了照顾那些不关程序,直接按Home键的人。不过这个函数可能会多次执行,所以要引入一个定时器,(间隔1小时),防止反复执行。

第三方平台

  • 基于JSPatch开源代码,出现了iOS App 热更新服务平台

  • 思考过就知道,JSPatch API的使用已经非常简单,但是补丁js文件的存储,加解密,传输,版本管理才是麻烦事。这个平台的SDK就是做这些的

  • 就像友盟统计,极光推送,热更新SDK也是差不多的,很小的一个功能入手,做一个服务平台。也像Java中的各种服务架构

  • 至于Swift,静态语言,以后怎么发展,不清楚,至少现在占比还太小

  • JavaScript目前的趋势越来越强,不得不关注。动态特性是最重要的特点。

参考文章

JSPatch使用小记

JSPatch 实现原理详解

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 14,205评论 4 61
  • 建立内网日记是为了实现交互的效果,使用的协议是比较简单的UDP协议,通过socket进行通讯功能,实现C/S 模型...
    果三代阅读 3,081评论 0 0
  • 理塘,素有世界高城之称的城市。 进藏前,很多人说如果能够平安无事的过了理塘,那接下去的日子就不需要害怕高反了;怀揣...
    韦小露阅读 3,928评论 2 3
  • 用简书第一天,想借此认知自己!
    蜗牛_9214阅读 942评论 0 0
  • 我的营养早餐,像一条美丽的彩虹。 黄白相间的杂粮馒头为我提供b族维生素,让我大脑清醒,认真听课。绿色的生菜为我提供...
    小王子WXN阅读 2,286评论 0 1