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一般都不正常,热补丁本身就没有多少意义。
JSPatch相关内容预研_第1张图片
执行流程-无缓存.jpg
  • 观点2:需要缓存,同一份补丁只要下载一次就好,没有必要重复下载。并且,下载还有延迟,也不能保证文件一定很小。没网络的情况下,有缓存也能起到热更新的作用。
JSPatch相关内容预研_第2张图片
执行流程-有缓存.jpg
  • 观点3:补丁的执行不能依赖网络。执行的是缓存中的补丁文件。有网络,需要更新补丁文件,才下载更新,替换补丁文件。这个方案的问题就是第一次肯定没补丁,要先下载,下次启动再执行补丁文件。另外,网络,下载可能需要耗费比较长的时间,补丁执行太靠后,Bug可能还是会重现。所以,执行补丁和下载更新补丁应该是两个完全不同的过程。最终,这种观点被团队采纳。
    先执行,再下载;下载的文件等下次启动再用。
JSPatch相关内容预研_第3张图片
缓存执行.jpg
JSPatch相关内容预研_第4张图片
补丁文件下载.jpg

更新时机

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

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

第三方平台

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

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

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

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

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

参考文章

JSPatch使用小记

JSPatch 实现原理详解

你可能感兴趣的:(JSPatch相关内容预研)