市场上现存方案:微软的 CodePush 以及React-Native中文网的Pushy,大家可根据公司实际情况酌情选择。
处于安全性的考虑,公司禁止向第三方平台上传源码相关文件,所以要自己动手实现。

增量更新主要实现流程
1.使用react-native bundle 命令打包,压缩打包文件
2.使用bsdiff生成新旧RN版本压缩文件的差异化文件patchFile
3.客户端旧RN版本压缩文件合并下载的patchFile文件,校验文件MD5值,解压合并后的文件,重新加载jsbundle,完成更新
4.增加版本控制,脚本化1、2过程

常见问题:
一、bsdiff的使用
下载地址:http://www.daemonology.net/bsdiff/
1.解压下载文件

$ cd bsdiff-4.3

2.修改makefile文件格式如下,原文件后三行缩进格式不对:

CFLAGS        +=    -O3 -lbz2PREFIX        ?=    /usr/local
INSTALL_PROGRAM    ?=    ${INSTALL} -c -s -m 555
INSTALL_MAN    ?=    ${INSTALL} -c -m 444all:        bsdiff bspatch
bsdiff:        bsdiff.c
bspatch:    bspatch.cinstall:${INSTALL_PROGRAM} bsdiff bspatch ${PREFIX}/bin.ifndef WITHOUT_MAN${INSTALL_MAN} bsdiff.1 bspatch.1 ${PREFIX}/man/man1.endif

3.在bspatch.c文件中加入头文件

#include<sys/types.h>

4.终端执行make命令,生成bsdiff、bspatch文件

$ make

5.将bsdiff、bspatch文件拷贝到usr/local/bin 目录下
6.使用方式:

//生成差异文件
$ bsdiff oldFilePath newFilePath patchFilePath
//合并文件
$ bspatch oldFilePath newFilePath patchFilePath

二、客户端合并文件,工程需要添加libbz2.tbd
1.bsdiff.h

#ifndef bsdiff_h
#define bsdiff_h#define LBD_OK 0#define LBD_ERR_OPEN 1000
#define LBD_ERR_CLOSE 1005
#define LBD_ERR_MALLOC 1010
#define LBD_ERR_SEEK 1015
#define LBD_ERR_TELL 1020
#define LBD_ERR_READ 1025
#define LBD_ERR_WRITE 1030
#define LBD_ERR_CORRUPT 1035#define LBD_ERR_BZ 2000#include <stdio.h>int ff_patch(const char *oldf, const char *patchf, const char *newf);#endif /* bsdiff_h */

2.bsdiff.c

#include "bsdiff.h"
#include <stdio.h>
#include <stdint.h>
#include <bzlib.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include<sys/types.h>#define MIN(x,y) (((x)<(y)) ? (x) : (y))static off_t offtin(u_char *buf) {off_t y;y=buf[7]&0x7F;y=y*256;y+=buf[6];y=y*256;y+=buf[5];y=y*256;y+=buf[4];y=y*256;y+=buf[3];y=y*256;y+=buf[2];y=y*256;y+=buf[1];y=y*256;y+=buf[0];if(buf[7]&0x80) y=-y;return y;
}#pragma mark - Publicint ff_patch(const char *oldf, const char *patchf, const char *newf) {FILE *f, *cpf, *dpf, *epf;BZFILE *cpfbz2, *dpfbz2, *epfbz2;int cbz2err, dbz2err, ebz2err;int fd;ssize_t oldsize, newsize;ssize_t bzctrllen, bzdatalen;uint8_t header[32], buf[8];uint8_t *old, *new;off_t oldpos, newpos;off_t ctrl[3];off_t lenread;off_t i;if ((f = fopen(patchf, "r")) == NULL){return LBD_ERR_OPEN;}/* Read header */if (fread(header, 1, 32, f) < 32){if (feof(f)){return LBD_ERR_CORRUPT;}return LBD_ERR_READ;}/* Check for appropriate magic */// had to change this to use patches created with command line bsdiff//    if (memcmp(header, "LBDIFFXX", 8) != 0)if (memcmp(header, "BSDIFF40", 8) != 0){return LBD_ERR_CORRUPT;}/* Read lengths from header */bzctrllen = offtin(header + 8);bzdatalen = offtin(header + 16);newsize = offtin(header + 24);if ((bzctrllen < 0) || (bzdatalen < 0) || (newsize < 0)){return LBD_ERR_CORRUPT;}/* Close patch file and re-open it via libbzip2 at the right places */if (fclose(f)){return LBD_ERR_CLOSE;}if ((cpf = fopen(patchf, "r")) == NULL){return LBD_ERR_OPEN;}if (fseeko(cpf, 32, SEEK_SET)){return LBD_ERR_SEEK;}if ((cpfbz2 = BZ2_bzReadOpen(&cbz2err, cpf, 0, 0, NULL, 0)) == NULL){return LBD_ERR_BZ;}if ((dpf = fopen(patchf, "r")) == NULL){return LBD_ERR_OPEN;}if (fseeko(dpf, 32 + bzctrllen, SEEK_SET)){return LBD_ERR_SEEK;}if ((dpfbz2 = BZ2_bzReadOpen(&dbz2err, dpf, 0, 0, NULL, 0)) == NULL){return LBD_ERR_BZ;}if ((epf = fopen(patchf, "r")) == NULL){return LBD_ERR_OPEN;}if (fseeko(epf, 32 + bzctrllen + bzdatalen, SEEK_SET)){return LBD_ERR_SEEK;}if ((epfbz2 = BZ2_bzReadOpen(&ebz2err, epf, 0, 0, NULL, 0)) == NULL){return LBD_ERR_BZ;}if (((fd = open(oldf, O_RDONLY, 0)) < 0) ||((oldsize = lseek(fd, 0, SEEK_END)) == -1) ||((old = malloc(oldsize + 1)) == NULL) ||(lseek(fd, 0, SEEK_SET) != 0) ||(read(fd, old, oldsize) != oldsize) ||(close(fd) == -1)){return LBD_ERR_OPEN;}if ((new = malloc(newsize + 1)) == NULL)return LBD_ERR_MALLOC;oldpos = 0;newpos = 0;while (newpos < newsize){/* Read control data */for (i = 0;i <= 2; i++){lenread = BZ2_bzRead(&cbz2err, cpfbz2, buf, 8);if ((lenread < 8) || ((cbz2err != BZ_OK) &&(cbz2err != BZ_STREAM_END))){return LBD_ERR_CORRUPT;}ctrl[i] = offtin(buf);}/* Sanity-check */if (newpos + ctrl[0] > newsize){return LBD_ERR_CORRUPT;}/* Read diff string */lenread = BZ2_bzRead(&dbz2err, dpfbz2, new + newpos, ctrl[0]);if ((lenread < ctrl[0]) ||((dbz2err != BZ_OK) && (dbz2err != BZ_STREAM_END))){return LBD_ERR_CORRUPT;}/* Add old data to diff string */for (i=0; i < ctrl[0]; i++)if ((oldpos + i >= 0) && (oldpos + i < oldsize))new[newpos + i] += old[oldpos + i];/* Adjust pointers */newpos += ctrl[0];oldpos += ctrl[0];/* Sanity-check */if (newpos + ctrl[1] > newsize){return LBD_ERR_CORRUPT;}/* Read extra string */lenread = BZ2_bzRead(&ebz2err, epfbz2, new + newpos, ctrl[1]);if ((lenread < ctrl[1]) ||((ebz2err != BZ_OK) && (ebz2err != BZ_STREAM_END))){return LBD_ERR_CORRUPT;}/* Adjust pointers */newpos += ctrl[1];oldpos += ctrl[2];}/* Clean up the bzip2 reads */BZ2_bzReadClose(&cbz2err, cpfbz2);BZ2_bzReadClose(&dbz2err, dpfbz2);BZ2_bzReadClose(&ebz2err, epfbz2);if (fclose(cpf) || fclose(dpf) || fclose(epf)){return LBD_ERR_CLOSE;}/* Write the new file */if (((fd = open(newf, O_CREAT|O_TRUNC|O_WRONLY, 0666)) < 0) ||(write(fd, new, newsize) != newsize) || (close(fd) == -1)){return LBD_ERR_OPEN;}free(new);free(old);return LBD_OK;
}

三、iOS客户端解压缩工具:SSZipArchive

四、参考项目react-native-pushy

五、版本管理脚本化 待更新

iOS客户端React-Native增量更新实践相关推荐

  1. iOS开发者React Native学习路线

    2019独角兽企业重金招聘Python工程师标准>>> http://blog.talisk.cn/blog/2016/08/13/RN-Learning-path-for-iOS- ...

  2. React Native热更新(iOS)-Pushy

    React Native的出现,使的开发iOS代码出现了更便捷的方式.由于RN是使用脚本语言编写的,实现了"解释执行"的方式,而这种执行方式的修改只需替换脚步即可,不需要重新发布程 ...

  3. React Native for Android 实践 — 实现知乎日报客户端

    React Native for Android 的发布,对一个 Android 开发者来说还是有相当的吸引力的.通过前面这篇博客:React Native for Android 入门老虎好不容易入 ...

  4. React Native 热更新方案

    转载: https://blog.csdn.net/xiangzhihong8/article/details/73201421 随着 React Native 的不断发展完善,越来越多的公司选择使用 ...

  5. [深入剖析React Native]热更新之react-native-pushy使用指南(Android)

    本文使用RN版本:0.33.0 react-native-pushy是ReactNative中文网推出的代码热更新服务,github地址:https://github.com/reactnativec ...

  6. 58 同城 iOS 客户端组件体积分析与统计实践

    [导读]目前 58 旗下存在租房.安居客.招聘.二手车.黄页等多个业务线,其中每个业务线在 58 APP 中存在一个或多个业务 pod.在研发层面上,58 同城其实早已实现了并行研发,不过,在并行研发 ...

  7. React Native热更新方案

    随着 React Native 的不断发展完善,越来越多的公司选择使用 React Native 替代 iOS/Android 进行部分业务线的开发,也有不少使用 Hybrid 技术的公司转向了 Re ...

  8. (笔记) RN React Native 热更新(react-native-code-push) AppCenter

    苹果App允许使用热更新Apple's developer agreement, 为了不影响用户体验,规定必须使用静默更新. Google Play不能使用静默更新,必须弹框告知用户App有更新.中国 ...

  9. 兼容iOS Android,React Native兼容iOS Android的TabBar

    最近着手开发的一个兼容iOS.Android的TabBar.还在不断开发中! 欢迎fork,欢迎star. :p 自己捣鼓了个E文的readme,没啥难度凑合可看. react-native-tabs ...

最新文章

  1. jsp实现简单的分页
  2. 【 FPGA 】按键消抖与LED灯流动小实验
  3. xampp 无法启动mysql
  4. kswapd0 挖矿_bioset linux_linux bioset 进程 腾讯云
  5. 3D视觉——基恩士LJ-X系列线激光
  6. oracle行列互换sql,Oracle实现行列转换的方法分析
  7. rpcbind 、nfs无法启动问题
  8. 1400协议是什么和28181区别_gb28181协议常见流程简析
  9. matlab课后习题,Matlab 课后习题集
  10. 2021-04-02
  11. 程序员面试指南 - 自我介绍
  12. 怎么逼自己 成为一个上进的人
  13. 微信小程序实现一行滑动显示很多文字--scroll-view
  14. 笔记本电脑如何同时上内外网(通过usb外接网卡实现虚拟机连外网)
  15. win7记事本如何转换html,win7记事本程序在哪里 64位win7记事本程序怎么安装
  16. devops包括什么_名字叫什么? DevOps版。
  17. 北京大学肖臻老师《区块链技术与应用》ETH笔记 - 8.0 ETH挖矿难度的调整
  18. QT学习笔记-第三天
  19. Python列表、元组、字典 集合简单基础
  20. 打印机上显示无法连接到服务器,服务器连接打印机无法连接到服务器

热门文章

  1. Java数据结构(1.1):数据结构入门+线性表、算法时间复杂度与空间复杂度、线性表、顺序表、单双链表实现、Java线性表、栈、队列、Java栈与队列。
  2. 删除N天前的log4j日志
  3. 拯救者Y9000P 加装固态
  4. ad中电容用什么封装_何为无极性电容?是干什么用的?
  5. java计算机毕业设计新疆旅游专列订票系统源码+mysql数据库+lw文档+系统+调试部署
  6. 野人参多少钱一斤?走进野人参高价格背后的秘密
  7. 如何在 Ubuntu 20.04 / KylinOS-V10-SP1 上安装 Sublime Text 4
  8. URL的作用是什么?它由几部分组成?
  9. 模板会有多层镜像_【保持最新版本】EVE-NG 新版模板,镜像。2020-12-27有更新
  10. 这篇 Linux 总结的很棒啊!