本文由我们团队的丁武龙组内分享总结
前言
随着react-native的出现,让移动开发出现了更加便捷的方式,由于react-native使用的是脚本语言编写,实现了解释运行的方式,这种执行方式只需要替换脚本文件就可以了,不需要再次发布应用程序,极大的节省了发布时间和方便了迭代开发,本文主要讲述的热更新组件是国内开发的组件pushy,其功能类似于CodePush,但由于codePush是国外的,在国内访问的速度比较慢,pushy支持增量更新,最大化的降低更新的数据量,节约流量。
操作流程
1.要想使用pushy,那就先创建一个RN项目,终端输入
react-native init projectName --version 0.55.4 //指定0.55.4版本
2.安装update工具,因为pushy热更新需要uodate配合使用
npm install -g react-native-update-cli //每台电脑只需要运行一次即可
3.安装pushy组件,这里使用的是yarn方式,也可以使用npm方式
//yarn 方式
yarn add react-native-update
//npm 方式
npm install react-native-update --save
//link到项目中
react-native link react-native-update
配置Bundle URL
- 在iOS工程目录下,首先在工程target的Build Phases->Link Binary with Libraries中加入libz.tbd、libbz2.1.0.tbd
2.然后再AppDelegate.m文件下添加以下代码
...省略代码
#import "RCTHotUpdate.h"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *jsCodeLocation;
#if DEBUG
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
// 非DEBUG情况下启用热更新
jsCodeLocation=[RCTHotUpdate bundleURL];
#endif
......
}
3.iOS外的白名单配置
从iOS9开始,苹果要求以白名单的形式在Info.plist中列出外部的非https接口,以督促开发者部署https协议。在我们的服务部署https协议之前,请在Info.plist中添加如下例外
4.登录与创建应用
1.首先需要在update.reactnative.cn注册一个账号,然后cd到项目根目录下,执行命令
pushy login
email: <注册邮箱>
password: <密码>
执行完了之后会在项目根目录下自动生成一个.update文件,注(不要把这个文件上传到Git等CVS系统上。你可以在.gitignore末尾增加一行.update来忽略这个文件)登录完成之后即可创建安卓或者ios应用程序(每个账号不超过3个应用),两端程序需要分别创建
//ios
pushy createApp --platform ios
App Name: <输入应用名字>
//an
pushy createApp --platform android
App Name: <输入应用名字>
创建完应用之后,即可在项目里看到update.json文件,内容形式如下
{
"ios": {
"appId": 14954,
"appKey": "OEKJy0mUCcbaFR9UJrMFrEOH-k89FX44"
}
}
可以把update.json上传到Git等CVS系统上,与你的团队共享这个文件,它不包含任何敏感信息。当然,他们在使用任何功能之前,都必须首先输入pushy login进行登录。
以上步骤完成之后,现在下面给给项目添加热更新功能代码
热更新功能实现
获取Appkey
检查更新是必须提供appkey,创建应用的时候都会生成一个appkey,这个值保存在update.json文件中,可以在App.js文件获取appkey
import {Platform,} from 'react-native';
import updateConfig from './update.json';
const {appKey} = updateConfig[Platform.OS];
检查更新/下载更新内容
使用异步函数checkUpdate可以检测当前版本是否需要更新
checkUpdate(appKey)
.then(info => {
})
返回的info有一下几类情况
1.{expired: true}:该应用包(原生部分)已过期,需要去应用市场下载更新应用程序
2.{upToDate: true} 当前版本已经是最新版本,无需更新
3.{update: true} 表示有新的版本可以更新了。info的name、description字段可 以用于提示用户,而metaInfo字段则可以根据你的需求自定义其它属性(如是否静默更新、 是否强制更新等等)。另外还有几个字段,包含了完整更新包或补丁包的下载地址, react-native-update会首先尝试耗费流量更少的更新方式。将info对象传递给downloadUpdate作为参数即可。
切换版本
downloadUpdate返回的是一个hash字符串,是当前版本的唯一字符串.
可以使用switchVersion函数来快速切换版本,应用程序会立即加载,代码如下
import React, {Component} from 'react'
import {
Platform,
View,
Alert,
} from 'react-native'
import {
isFirstTime,
isRolledBack,
checkUpdate,
downloadUpdate,
switchVersion,
switchVersionLater,
markSuccess,
} from 'react-native-update'
...
componentWillMount() {
if (isFirstTime) {
Alert.alert('提示', '这是当前版本第一次启动,是否要模拟启动失败?失败将回滚到上一版本', [
{text: '是', onPress: () => { throw new Error('模拟启动失败,请重启应用') }},
{text: '否', onPress: () => { markSuccess() }},
])
} else if (isRolledBack) {
Alert.alert('提示', '刚刚更新失败了,版本被回滚.')
}
this.checkUpdate()
}
...
doUpdate = (info) => {
downloadUpdate(info).then((hash) => {
Alert.alert('提示', '下载完毕,是否重启应用?', [
{text: '是', onPress: () => { switchVersion(hash) }},
{text: '否'},
{text: '下次启动时', onPress: () => { switchVersionLater(hash) }},
])
}).catch((err) => {
Alert.alert('提示', '更新失败.')
})
};
checkUpdate = () => {
checkUpdate(appKey).then((info) => {
// alert(info.upToDate)
if (info.expired) {
Alert.alert('提示', '您的应用版本已更新,请前往应用商店下载新的版本', [
{text: '确定', onPress: () => {}},
])
} else if (info.upToDate) {
Alert.alert('提示', '您的应用版本已是最新.')
} else {
Alert.alert('提示', `检查到新的版本${info.name},是否下载?\n${info.description}`, [
{text: '是', onPress: () => { this.doUpdate(info) }},
{text: '否'},
])
}
}).catch((err) => {
Alert.alert('提示', '更新失败.')
})
}
...
现在可以通过update服务检查版本是否有更新了,
发布应用包和版本
注意 从发布版本到正式上线期间,不要更改脚本文件和资源,如果修改,可能会造成脚本出现问题,导致无法更新。
1.在真机模式或者Generic iOS Device模式下对项目打包,Product-Archive,打包完成之后,生成一个IPA文件,上传到分发平台进行下载测试,执行命令
pushy uploadIpa ipa路径
发布热更新包
修改一行代码(比如在App.js文件增加一个弹框),然后生成新的热更新版本。
pushy bundle --platform ios Bundling with React Native version: 0.55.4
.....
Would you like to publish it?(Y/N)
如果想要立即发布,输入Y即可,
Uploading [========================================================] 100% 0.0s
Enter version name: 1.100
Enter description: update
Enter meta info: {"ok":1}
Version published: 42053
Would you like to bind packages to this version?(Y/N)
此时版本已经提交到update服务,但用户暂时看不到此更新,你需要先将特定的包版本绑定到此热更新版本上
输入Y进行绑定
Y
21144(出现的这串数字要记住,下面要用到)) 1.1(normal) (newest)
Total 1 packages.
Enter packageId: 21144
Ok.
至此,热更新集成完成,