React Native codePush 重启后回滚
React Native codePush rollback after restart
我正在尝试实施 AppCenter CodePush 来更新 Javascript 代码,而无需通过 App Store 审核流程。
我已按照此处提到的 iOS 和 Android 步骤设置多部署环境:
https://github.com/microsoft/react-native-code-push/blob/master/docs/multi-deployment-testing-ios.md
https://github.com/microsoft/react-native-code-push/blob/master/docs/multi-deployment-testing-android.md
版本
"react-native": "0.59.10"
"react-native-code-push": "^5.6.1"
我尝试在 Android 上使用 react-native run-android --variant release
,在 iOS 上我将我的 运行 和存档方案更改为 STAGING。但在这两种情况下,他们似乎都像 [CodePush] Loading JS bundle from "assets://index.android.bundle"
那样获取我的包,而不是从 CodePush 存储库中获取。这是我看到的唯一输出(与 CodePush 相关)。
我像这样发布了 codePush:appcenter codepush release-react -a name/appName-1 -d Staging
。此命令成功,我在 iOS 和 Android 登台环境中看到它具有正确的版本。
componentDidMount
componentDidMount() {
codePush.notifyApplicationReady();
...
codePush.sync({
updateDialog: true,
installMode: codePush.InstallMode.IMMEDIATE
});
}
导出应用程序
App = codePush({
checkFrequency: codePush.CheckFrequency.ON_APP_RESUME
})(App);
AppRegistry.registerComponent("myApp", () => App);
Info.plist
CodePushDeploymentKey: $(CODEPUSH_KEY)
android/app/build.gradle
buildTypes {
debug {
buildConfigField "String", "CODEPUSH_KEY", '""'
}
releaseStaging {
buildConfigField "String", "CODEPUSH_KEY", '"my_code"'
matchingFallbacks = ['release']
}
release {
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
signingConfig signingConfigs.release
buildConfigField "String", "CODEPUSH_KEY", '"my_code"'
}
}
我的构建设置包含 codePush 发布和暂存代码。
我也尝试将 CodePush Staging 版本升级到生产环境,但这并没有解决我的问题。
appcenter codepush deployment list -a Name/MyApp
总是 returns 0(1 个待处理)。
更新
它要求更新应用程序,批准后成功更新应用程序。但是当我重新启动应用程序时,它回滚到以前的版本。
更新 2
AppDelgate.m 变化:
#import <CodePush/CodePush.h>
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
return [CodePush bundleURL];
#endif
MainApplication.java 变化:
import com.microsoft.codepush.react.CodePush;
@Override
protected String getJSBundleFile() {
return CodePush.getJSBundleFile();
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
..
new CodePush(BuildConfig.CODEPUSH_KEY, MainApplication.this, BuildConfig.DEBUG),
build.gradle 变化:
buildTypes {
debug {
buildConfigField "String", "CODEPUSH_KEY", '""'
}
releaseStaging {
buildConfigField "String", "CODEPUSH_KEY", '"<staging_key>"'
matchingFallbacks = ['release']
}
release {
..
buildConfigField "String", "CODEPUSH_KEY", '"<prod_key>"'
}
}
您是否在模拟器中对此进行测试?
如果是这样,做一个reload
在CodePush眼里基本上就是模拟崩溃
如果您 运行 在模拟器中,CodePush 的行为将与在未绑定到打包程序的真实设备上不同。测试它的最佳方法是构建并将该构建上传到商店以分发到您的测试池。
然后您可以通过 Google Play 商店或 iOS 的 testflight 下载并安装您的构建,并在那里测试您的 CodePush 安装。
编辑:
经过交谈并更改了以下代码,我们开始工作了:
首先,创建一个选项对象,并在我们的 codePush 调用中使用它:
const options = {
updateDialog: true,
installMode: codePush.InstallMode.IMMEDIATE,
checkFrequency: codePush.CheckFrequency.ON_APP_RESUME
};
然后我们可以调用codePush同步如下:
codePush.sync(options);
最后,我们没有将 codePush 设置分配给 App
,而是将其全部移动到一行中:
AppRegistry.registerComponent("myApp", () =>
codePush(options)(App)
);
我不是 codePush 专家,我不知道是否需要选项部分,尽管我认为在不同点有不同的选项可能会导致不一致。
我确实认为调用 App = codePush(options)(App)
引起了问题。
无论哪种方式,结合使用这两种方法都可以解决问题。
我遇到了同样的问题,所以我只是在我的应用登录页面上记下了 codePush.notifyAppReady(),并确保在检查新更新之前执行此操作
componentDidMount(): void {
codePush.notifyAppReady()
this.checkUpdate();
}
checkUpdate = async () => {
const updateData: RemotePackage | null = await codePush.checkForUpdate()
if (updateData && !updateData.failedInstall) {
//your code
this.setState({
isMandatory: updateData.isMandatory,
whatsNew: updateData.description,
showAppUpdateDialog: true
})
}
}
就我而言,我手动使用 codePush.sync
。在 the docs of codepush 中,他们说:
Notifies the CodePush runtime that a freshly installed update should be considered successful, and therefore, an automatic client-side rollback isn't necessary. It is mandatory to call this function somewhere in the code of the updated bundle. Otherwise, when the app next restarts, the CodePush runtime will assume that the installed update has failed and roll back to the previous version. This behavior exists to help ensure that your end users aren't blocked by a broken update.
他们建议在成功更新后使用 notifyAppReady
。但是,我找不到合适的地方来用 react-navigation 调用它。相反,在导航组件的根目录中,创建了这个变量
const codePushOptions = { checkFrequency: codePush.CheckFrequency.MANUAL };
组件导出为
export default codePush(codePushOptions)(App);
我正在尝试实施 AppCenter CodePush 来更新 Javascript 代码,而无需通过 App Store 审核流程。
我已按照此处提到的 iOS 和 Android 步骤设置多部署环境: https://github.com/microsoft/react-native-code-push/blob/master/docs/multi-deployment-testing-ios.md https://github.com/microsoft/react-native-code-push/blob/master/docs/multi-deployment-testing-android.md
版本
"react-native": "0.59.10"
"react-native-code-push": "^5.6.1"
我尝试在 Android 上使用 react-native run-android --variant release
,在 iOS 上我将我的 运行 和存档方案更改为 STAGING。但在这两种情况下,他们似乎都像 [CodePush] Loading JS bundle from "assets://index.android.bundle"
那样获取我的包,而不是从 CodePush 存储库中获取。这是我看到的唯一输出(与 CodePush 相关)。
我像这样发布了 codePush:appcenter codepush release-react -a name/appName-1 -d Staging
。此命令成功,我在 iOS 和 Android 登台环境中看到它具有正确的版本。
componentDidMount
componentDidMount() {
codePush.notifyApplicationReady();
...
codePush.sync({
updateDialog: true,
installMode: codePush.InstallMode.IMMEDIATE
});
}
导出应用程序
App = codePush({
checkFrequency: codePush.CheckFrequency.ON_APP_RESUME
})(App);
AppRegistry.registerComponent("myApp", () => App);
Info.plist
CodePushDeploymentKey: $(CODEPUSH_KEY)
android/app/build.gradle
buildTypes {
debug {
buildConfigField "String", "CODEPUSH_KEY", '""'
}
releaseStaging {
buildConfigField "String", "CODEPUSH_KEY", '"my_code"'
matchingFallbacks = ['release']
}
release {
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
signingConfig signingConfigs.release
buildConfigField "String", "CODEPUSH_KEY", '"my_code"'
}
}
我的构建设置包含 codePush 发布和暂存代码。
我也尝试将 CodePush Staging 版本升级到生产环境,但这并没有解决我的问题。
appcenter codepush deployment list -a Name/MyApp
总是 returns 0(1 个待处理)。
更新 它要求更新应用程序,批准后成功更新应用程序。但是当我重新启动应用程序时,它回滚到以前的版本。
更新 2 AppDelgate.m 变化:
#import <CodePush/CodePush.h>
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
return [CodePush bundleURL];
#endif
MainApplication.java 变化:
import com.microsoft.codepush.react.CodePush;
@Override
protected String getJSBundleFile() {
return CodePush.getJSBundleFile();
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
..
new CodePush(BuildConfig.CODEPUSH_KEY, MainApplication.this, BuildConfig.DEBUG),
build.gradle 变化:
buildTypes {
debug {
buildConfigField "String", "CODEPUSH_KEY", '""'
}
releaseStaging {
buildConfigField "String", "CODEPUSH_KEY", '"<staging_key>"'
matchingFallbacks = ['release']
}
release {
..
buildConfigField "String", "CODEPUSH_KEY", '"<prod_key>"'
}
}
您是否在模拟器中对此进行测试?
如果是这样,做一个reload
在CodePush眼里基本上就是模拟崩溃
如果您 运行 在模拟器中,CodePush 的行为将与在未绑定到打包程序的真实设备上不同。测试它的最佳方法是构建并将该构建上传到商店以分发到您的测试池。
然后您可以通过 Google Play 商店或 iOS 的 testflight 下载并安装您的构建,并在那里测试您的 CodePush 安装。
编辑:
经过交谈并更改了以下代码,我们开始工作了:
首先,创建一个选项对象,并在我们的 codePush 调用中使用它:
const options = {
updateDialog: true,
installMode: codePush.InstallMode.IMMEDIATE,
checkFrequency: codePush.CheckFrequency.ON_APP_RESUME
};
然后我们可以调用codePush同步如下:
codePush.sync(options);
最后,我们没有将 codePush 设置分配给 App
,而是将其全部移动到一行中:
AppRegistry.registerComponent("myApp", () =>
codePush(options)(App)
);
我不是 codePush 专家,我不知道是否需要选项部分,尽管我认为在不同点有不同的选项可能会导致不一致。
我确实认为调用 App = codePush(options)(App)
引起了问题。
无论哪种方式,结合使用这两种方法都可以解决问题。
我遇到了同样的问题,所以我只是在我的应用登录页面上记下了 codePush.notifyAppReady(),并确保在检查新更新之前执行此操作
componentDidMount(): void {
codePush.notifyAppReady()
this.checkUpdate();
}
checkUpdate = async () => {
const updateData: RemotePackage | null = await codePush.checkForUpdate()
if (updateData && !updateData.failedInstall) {
//your code
this.setState({
isMandatory: updateData.isMandatory,
whatsNew: updateData.description,
showAppUpdateDialog: true
})
}
}
就我而言,我手动使用 codePush.sync
。在 the docs of codepush 中,他们说:
Notifies the CodePush runtime that a freshly installed update should be considered successful, and therefore, an automatic client-side rollback isn't necessary. It is mandatory to call this function somewhere in the code of the updated bundle. Otherwise, when the app next restarts, the CodePush runtime will assume that the installed update has failed and roll back to the previous version. This behavior exists to help ensure that your end users aren't blocked by a broken update.
他们建议在成功更新后使用 notifyAppReady
。但是,我找不到合适的地方来用 react-navigation 调用它。相反,在导航组件的根目录中,创建了这个变量
const codePushOptions = { checkFrequency: codePush.CheckFrequency.MANUAL };
组件导出为
export default codePush(codePushOptions)(App);