集成
原理
环境
- node:v16.13.2
- npm:8.1.2
- yarn:1.22.17
- react:17.0.2
- react-native:0.67.2,
- react-native-code-push:^7.0.4
- Xcode:Version 13.2.1 (13C100)
- Android Studio:Android Studio Bumblebee | 2021.1.1 Patch 1
- Gradle:com.android.tools.build:gradle:7.1.1
集成
安装appcenter
npm install -g appcenter-cli
AppCenter相关操作
登录操作
1、终端中输入登录命令:appcenter login
,执行后会自动打开浏览器让你选择一种登录方式,我选的是github
2、登录后会生成一串token,复制下来
其它命令
- 查看配置:
appcenter profile list
- 退出登录:
appcenter logout
- 查看所有的登录token:
appcenter tokens list
- 删除一个token:
appcenter tokens delete <machineName>
ReactNative项目中使用
为iOS和安卓分别创建App
针对不同系统分别执行下面的命令
appcenter apps create -d <appDisplayName> -o <operatingSystem> -p <platform>
例如针对iOS和安卓分别执行如下命令
appcenter apps create -d RNDemoAndroid -o Android -p React-Native
appcenter apps create -d RNDemoiOS -o iOS -p React-Native
在Appcenter创建完App之后需要针对每个App创建Staging和Production 环境对应的Key
appcenter codepush deployment add -a <ownerName>/RNDemoiOS Staging
appcenter codepush deployment add -a <ownerName>/RNDemoiOS Production
备注:将ownerName替换成你在Appcenter的用户名
最后我们将得到iOS和Android两组共四个CodePush Deployment Key,如下图所示
ReactNative项目安装CodePush
cd到你的ReactNative项目目录下,执行命令
npm install --save react-native-code-push
ReactNative中iOS项目修改
为iOS项目安装依赖
在项目目录中执行 cd ios && pod install && cd ..
安装pod文件中的依赖并返回到项目主目录
使用Xcode打开ios主目录下的.xcworkspace文件编辑AppDelegate.m
引入CodePush头文件
将代码 [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
替换为return [CodePush bundleURL];
如图所示
iOS多环境配置
1、创建三个环境的xcconfig文件
2、将codepush中stage和production环境对应的deployment key写到对应的文件中
3、在项目中添加一个stage环境的configuration(我是直接 Duplicate "Realse")并对各个环境选择对应的xcconfig文件,如图所示
4、新建Scheme,建议名称也可以使用Debug、Stage、Release,然后Edit Scheme,将每个环境的Buid Configuration修改为对应值
5、配置多环境的意义不止如此,你可以为不同环境设置不同的AppIcon、证书、名称,还有各种自定义的变量,如图所示
可以为项目不同环境添加User-Defined常量,这里就不展开说了。
6、修改项目中的Info.plist文件,key为CodePushDeploymentKey,value为xcconfig文件中的值${RN_DEMO_CODE_PUSH_DEPLOYMENT_KEY}
这样就完成了iOS多环境配置
ReactNative中Android项目修改
修改android/settings.gradle,添加如下代码
include ':app', ':react-native-code-push'
project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')
修改android/app/build.gradle
在文件中找到
apply from: "../../node_modules/react-native/react.gradle"
在这一行下面添加
apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"
修改MainApplication.java文件
...
// 1. Import the plugin class.
import com.microsoft.codepush.react.CodePush;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
...
// 2. Override the getJSBundleFile method to let
// the CodePush runtime determine where to get the JS
// bundle location from on each app start
@Override
protected String getJSBundleFile() {
return CodePush.getJSBundleFile();
}
};
}
Android多环境设置
在 build.gradle(:app)中找到buildTypes代码块,并作如下修改
将<INSERT_STAGING_KEY>替换成你在codepush中的deploymentKey
buildTypes {
debug {
signingConfig signingConfigs.debug
if (nativeArchitectures) {
ndk {
abiFilters nativeArchitectures.split(',')
}
}
// Note: CodePush updates shouldn't be tested in Debug mode as they're overriden by the RN packager. However, because CodePush checks for updates in all modes, we must supply a key.
resValue "string", "CodePushDeploymentKey", '""'
}
//**************************添加代码start***************************************
releaseStaging {
// Caution! In production, you need to generate your own keystore file.
// see https://reactnative.dev/docs/signed-apk-android.
signingConfig signingConfigs.archive
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
resValue "string", "CodePushDeploymentKey", '"<INSERT_STAGING_KEY>"'
//https://stackoverflow.com/questions/52777665/react-native-code-push-unable-to-resolve-dependency-for-appreleasestaging-com
//添加这个不然运行的时候报错
matchingFallbacks = ["release"]
}
//**************************添加代码end***************************************
release {
// Caution! In production, you need to generate your own keystore file.
// see https://reactnative.dev/docs/signed-apk-android.
signingConfig signingConfigs.archive
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
resValue "string", "CodePushDeploymentKey", '"<INSERT_STAGING_KEY>"'
}
}
ReactNative TS/JS代码修改
Code Push API更新的时候判断的版本为 package.json 中最顶端的version字段,每次更新的时候需要修改version,作为demo,我直接在App.tsx中修改了代码,没有创建新的component
const App = () => {
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
//检查更新方法
const checkForUpdate = () => {
CodePush.sync({
installMode: CodePush.InstallMode.IMMEDIATE,
},(status: CodePush.SyncStatus)=>{
switch (status) {
case CodePush.SyncStatus.UP_TO_DATE:{
Alert.alert("提示","当前已经是最新版本")
}
break;
case CodePush.SyncStatus.UPDATE_INSTALLED:{
Alert.alert("提示","最新版本已安装")
}
break;
default:
break
}
console.log(status)
},()=>{
});
};
//清除更新
const clear = () => {
CodePush.clearUpdates();
};
var name = packageInfo.name;
var version = packageInfo.version;
return (
<SafeAreaView style={backgroundStyle}>
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={backgroundStyle}>
<Header />
<View
style={{
backgroundColor: isDarkMode ? Colors.black : Colors.white,
}}>
<Section title="项目名称">
<Text style={styles.highlight}>{name}</Text>
</Section>
<Section title="版本号">
<Text style={styles.highlight}>{version}</Text>
</Section>
<Section title="Version Info">
<Button title='检查更新' onPress={checkForUpdate}/>
<Button title='清除更新' onPress={clear}/>
</Section>
</View>
</ScrollView>
</SafeAreaView>
);
};
打包bundle
改变package.json中的version对应的版本号 然后运行命令为iOS端打包jsbundle
appcenter codepush release-react -a yourusername@163.com/RNDemoiOS