共计 5429 个字符,预计需要花费 14 分钟才能阅读完成。
CodePush 简介
作为一个跨平台应用开发框架,React Native 虽然在动态更新方面提供了动态更新的基础,但是动态更新技术并没有想象的那么完善。好在微软开发了 CodePush,填补了 React Native 应用在动态更新方面的空白。
CodePush 是微软提供的一套用于 React Native 和 Cordova 的热更新服务,借助 CodePush,开发者可以直接部署移动应用更新并快速实现代码的热更新,CodePush 的官方地址为 https://microsoft.github.io/c…。
CodePush 作为一个中央仓库,开发者可以实时推送更新,然后客户端应用可以在应用启动时查询更新。借助 CodePush,不需要重新审核和安装应用,就可以解决应用的缺陷和添加新特性。CodePush 支持的功能如下:
• 支持直接对用户部署代码更新;
• 管理 Alpha、Beta 和生产环境应用;
• 支持 React Native 和 Cordova 跨平台技术的热更新;
• 支持 JavaScript 文件与图片资源的更新;
CodePush 安装与账号注册
使用 CodePush 之前,需要先安装 CodePush 命令行工具,并注册 CodePush 账号和应用,安装命令如下:
npm install -g code-push-cli
安装完成后可以通过 code-push - v 命令进行验证。然后,在终端输入命令 code-push register,会打开注册页面让开发者选择授权账号,如图 11-11 所示。
授权通过之后,CodePush 会生成一个 access key,复制此 key 到终端即可完成注册,如图 11-12 所示。
除了 code-push register 命令外,CodePush 常用的命令还有:
• code-push login:登录 CodePush
• code-push logout: 注销 CodePush
• code-push access-key ls:列出 access-key
• code-push access-key rm <accessKey>:删除某个 access-key
为了让 CodePush 服务器知道创建的应用,还需要向服务器进行注册,注册的命令如下:
code-push app add <appName> <platform> react-native
其中,appName 表示应用的名称,platform 表示应用的平台。在终端输入命令后即可完成应用的注册,如图 11-13 所示。
向 CodePush 添加应用时需要指明应用的平台,成功注册 CodePush 应用后,每个应用都会生成两个 deployment key。其中,Production 是用于生产环境的 deployment key,Staging 则是用于模拟环境的 deployment key。
注册成功后,可以通过 https://appcenter.ms/apps 来查 …,如图 11-14 所示。
需要说明的是,如果需要同时发布 Android 和 iOS 两个平台的热更新,那么在注册 CodePush 应用时需要注册两个应用,并获取两套 deployment key。
除了 code-push app add 命令外,CodePush 用于应用管理的命令还有:
• code-push app add:在登录账号中添加一个新的应用。
• code-push app remove <appName>:在登录账号中删除一个存在的应用。
• code-push app rename:重命名一个存在的应用。
• code-push app list:列出登录账号下所有的应用。
• code-push app transfer:把应用的所有权转移到另外一个账号。
集成 CodePush SDK
完成 CodePush 账号的创建和应用的注册操作之后,接下来还需要集成 CodePush SDK 到 React Native 应用中。
首先,使用 react-native init 命令新建一个 React Native 项目,如下所示:
react-native init codepush
然后,安装 react-native-code-push 插件,安装命令如下:
npm install --save react-native-code-push
然后,运行 link 命令将 react-native-code-push 插件添加到原生工程中,如下所示:
react-native link react-native-code-push
此时,系统会提示输入 iOS 和 Android 应用的 deployment key,此时输入应用的 Staging 即可,如果不输入则可以直接点击【Enter】键跳过,如下所示:
? What is your CodePush deployment key for Android (hit <ENTER> to ignore)
? What is your CodePush deployment key for iOS (hit <ENTER> to ignore)
如果忘记 deployment key 的话,可以通过如下命令进行查看,如图 11-14 所示。
需要说明的是,使用 react-native link 命令链接原生库时,如果直接跳过输入 deployment key,也可以在原生端手动配置。
成功添加 react-native-code-push 到 CodePush 项目后,还需要对原生工程做一些修改。
手动集成 CodePush SDK
使用 react-native link 链接原生库时,如果跳过输入 deployment key,也可以在原生端手动进行配置。
对于 iOS 来说,使用 Xcode 打开 ios/codepush.xcodeproj 目录下的 iOS 工程,然后 Xcode 的导航视图的 PROJECT 下选中项目,然后依次选择【Info】→【Configurations】→【添加】→【Duplicate Release Configuration】,然后输入 Staging 的 key,如图 11-15 所示。
然后,在 Build Settings 面板选择【add User-Defined Setting】添加自定义编译环境配置,如图 11-17 所示。
然后,在 User-Defined 中添加 CodePush 的 deployment key,如图 11-18 所示。
打开 Info.plist 文件,并在 CodePushDeploymentKey 列的 Value 选项中输入 $(CODEPUSH_KEY),如图 11-19 所示。
对于 Android 来说,使用 Android Studio 打开 android 工程,然后在工程的 android/settings.gradle 文件中引入 react-native-code-push 库,如下所示:
include ':react-native-code-push'
project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')
然后,在 app/build.gradle 文件中关联 react-native-code-push 库的依赖,如下所示:
apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"
dependencies {compile project(':react-native-code-push')
}
接下来,在 MainApplication 类的 getPackages() 方法中注册 CodePush,如下所示:
@Override
protected String getJSBundleFile() {return CodePush.getJSBundleFile();
}
@Override
public boolean getUseDeveloperSupport() {return BuildConfig.DEBUG;}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(new MainReactPackage(),
new CodePush(BuildConfig.codepushkey,getApplicationContext(), BuildConfig.DEBUG)
);
}
由于 CodePush 的 deployment-key 分为生产环境与测试环境两种,所以可以在 build.gradle 文件中进行设置,如下所示:
android {
releaseStaging {buildConfigField "String", "CODEPUSH_KEY", '"<INSERT_STAGING_KEY>"'}
release {buildConfigField "String", "CODEPUSH_KEY", '"<INSERT_PRODUCTION_KEY>"'}
}
}
到此,CodePush 热更新所需要的原生配置就完成了,接下来只需要修改 React Native 的逻辑即可。
iOS 应用热更新示例
使用 Xcode 打开 ios/codepush.xcodeproj 文件,然后打开 AppDelegate.m 文件,可以看到此时 jsCodeLocation 相关代码如下:
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
return [CodePush bundleURL];
#endif
}
从上面的代码可以看出,在非 Debug 状态下,系统默认加载的资源地址为 CodePush 的 bundleURL,为了加载 CodePush 的 Bundle 资源,需要手动修改编译选项为 Release。具体来说,打开 Xcode 的菜单,然后依次选择【Product】→【Scheme】→【Edit Scheme】,如图 11-19 所示。
完成上述原生配置之后,接着打开 React Native 的入口文件 index.js,并对 index.js 文件进行如下的修改。
import React, {Component} from 'react';
import {AppRegistry, Platform, StyleSheet, Text, View} from 'react-native';
import {name as appName} from './app.json';
import codePush from 'react-native-code-push'
type Props = {};
export default class App extends Component<Props> {constructor(props) {super(props);
this.state = {message: ''};
}
componentDidMount() {codePush.checkForUpdate().then((update) => {if (update) {this.setState({message: '有新的更新!'})
} else {this.setState({message: '已是最新,不需要更新!'})
}
})
}
render() {
return (<View style={styles.container}>
<Text style={styles.welcome}> 版本号 1.0</Text>
<Text style={styles.instructions}>{this.state.message}</Text>
</View>
);
}
}
// 省略样式文件
AppRegistry.registerComponent(appName, () => codePush(App));
如上所示,可以 componentDidMount 生命周期函数会检查 CodePush 应用是否需要更新,如果检测需要更新则下载 CodePush 应用的更新。重新编译和运行应用,效果如图 11-21 所示。
然后,将 index.js 文件显示的版本号升级为 1.1,修改内容如下:
render() {
return (<View style={styles.container}>
<Text style={styles.welcome}> 版本号 1.1</Text>
<Text style={styles.instructions}>{this.state.message}</Text>
</View>
);
}
接下来,使用 CodePush 的 code-push release 命令行工具发布 iOS 的更新,如下所示:
code-push release-react codepush ios
等待系统打包并发布热更新的 bundle 文件,发布成功后关闭并重新打开应用,就可以看到应用启动时会提示更新,如图 11-22 所示。
在检测到更新后,系统会下载最新的资源并更新,当再次关闭并重新打开应用时,可以看到应用更新成功后的效果。并且,还可以使用 CodePush 提供的 code-push deployment 命令来查看更新情况,如图 11-23 所示。
和 iOS 的应用热更新类似,Android 应用的热更新也可以使用这一步骤。