以下是基于 CodePush 的热更新计划的实际,有须要的能够参考一下:
一、配置 appcenter
1.1 装置 appcenter
装置 appcenter 的命令如下:
npm install -g appcenter-cli
/** 装置实现后 */
appcenter help
/** 如果呈现帮忙指令阐明装置胜利 */
装置胜利之后,登录 appcenter,波及的命令如下:
appcenter login
执行后在关上的浏览器抉择一种登陆形式登陆(关上的网页须要挂代理)。
登陆胜利后会取得 token, 将 token 填入控制台实现登陆。
登陆胜利后,执行如下命令能够查看登陆信息。
appcenter profile list
1.2 创立不同平台的 App
创立的命令格局如下:
appcenter apps create -d <appDisplayName> -o <operatingSystem> -p <platform>
比方,上面是只思考 iOS 和 Android 平台。
appcenter apps create -d RNDemoAndroid -o Android -p React-Native
appcenter apps create -d RNDemoiOS -o iOS -p React-Native
接着,创立 App 在 Staging 和 Production 环境的部署 key,命令如下。
//ios
appcenter codepush deployment add -a <ownerName>/RNDemoiOS Staging
appcenter codepush deployment add -a <ownerName>/RNDemoiOS Production
//android
appcenter codepush deployment add -a <ownerName>/RNDemoAndroid Staging
appcenter codepush deployment add -a <ownerName>/RNDemoAndroid Production
以上 shell 命令都会返回胜利的提醒。接下来,再执行一下语句。
// 自行替换
ownername appName appcenter codepush deployment list -a <ownerName>/<appName> -k
到此,appcenter 配置过程就实现了。对于 Appcenter 的应用和配置,能够参考上面的内容。
https://github.com/microsoft/appcenter-cli
https://learn.microsoft.com/zh-cn/appcenter/
二、react-native-code-push 装置及配置
2.1 装置
装置的命令如下:
yarn add react-native-code-push cd ios && pod install
2.2 iOS 配置
此处只针对 react-native 0.60 版本及以上配置,配置前请确保已装置必须的 CocoaPods 依赖项。关上 AppDelegate.m 文件,并为 CodePush 标头增加导入语句:
#import <CodePush/CodePush.h>
AppDelegate.m 的代码如下 (留神:#import 必须在 FB_SONARKIT_ENABLED 后面,否则 ios archive 会报错)。
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
//** 引入热更新
#import <CodePush/CodePush.h>
#ifdef FB_SONARKIT_ENABLED
#import <FlipperKit/FlipperClient.h>
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
#import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
#import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
#import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>
而后替换上面的代码:
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
// 替换为
return [CodePush bundleURL];
减少部署的 key 值到 info.plist 中。
<key>CodePushDeploymentKey</key>
<string>xxx</string>
更多的内容以及配置 react-native 版本 0.6 以下的详见内容:https://github.com/microsoft/react-native-code-push/blob/master/docs/setup-ios.md。
2.3 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 文件,而后引入以 CodePush 代码。
...
// 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 in order 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();
}
};
}
将部署的 key 退出到 strings.xml。
<resources>
<string name="app_name">AppName</string>
//xxx 是部署的 key
<string moduleConfig="true" name="CodePushDeploymentKey">xxx</string>
</resources>
更多的配置,请参考:https://github.com/microsoft/react-native-code-push/blob/master/docs/setup-android.md
2.4 遇到的问题
1,Xcode 运行我的项目到模拟器的时候报错:Could not build module ‘Foundation’。
解决办法:更新 mac 零碎到最新,更新 xcode 版本到最新!!!
2,Xcode archive 我的项目打包时提醒:use of undeclared identifier ‘CodePush’
解决办法:#import 必须在 FB_SONARKIT_ENABLED 后面,否则 ios archive 会报错
三、React Native 我的项目代码
3.1 批改代码
为了实现 RN 的更新,咱们还须要对 RN 我的项目的代码进行批改。首先,须要在我的项目的入口文件中引入 CodePush,并增加如下逻辑:
//for class
import codePush from "react-native-code-push";
class MyApp extends Component { }
MyApp = codePush(MyApp);
//for hook
import codePush from "react-native-code-push";
const MyAp = () => {}
// 如果须要更快更新,能够将 MyApp = codePush(MyApp) 增加;
// let codePushOptions = {checkFrequency: codePush.CheckFrequency.ON_APP_RESUME};
// MyApp = codePush(codePushOptions)(MyApp);
MyApp = codePush(MyApp);
如果须要手动查看更新,也能够应用上面的代码:
let codePushOptions = {checkFrequency: codePush.CheckFrequency.MANUAL};
class MyApp extends Component {onButtonPress() {
codePush.sync({
updateDialog: true,
installMode: codePush.InstallMode.IMMEDIATE
});
}
render() {
return (
<View>
<TouchableOpacity onPress={this.onButtonPress}>
<Text>Check for updates</Text>
</TouchableOpacity>
</View>
)
}
}
MyApp = codePush(codePushOptions)(MyApp);
3.2 疾速验证代码
上面,我提供了疾速验证成果的示例代码。替换 app.tsx 为以下代码能够疾速验证热更新成果。
/* eslint-disable no-lone-blocks */
/* eslint-disable react-native/no-inline-styles */
import React from 'react';
import type {Node} from 'react';
import {
SafeAreaView,
Text,
Alert,
useColorScheme,
TouchableOpacity,
View,
Image,
} from 'react-native';
import testImg from './assets/test.png';
import Video from 'react-native-video';
import CodePush from 'react-native-code-push';
import consultant from './assets/video/consultant.mp4';
const App: () => Node = () => {
const backgroundStyle = {
backgroundColor: '#fff',
flex: 1,
};
const check = () => {
CodePush.sync(
{installMode: CodePush.InstallMode.IMMEDIATE,},
(status: CodePush.SyncStatus) => {console.log(status, CodePush.SyncStatus);
switch (status) {
case CodePush.SyncStatus.UP_TO_DATE:
{Alert.alert('曾经是最新版本');
}
break;
case CodePush.SyncStatus.DOWNLOADING_PACKAGE:
{Alert.alert('正在下载更新包');
}
break;
case CodePush.SyncStatus.UPDATE_INSTALLED:
{Alert.alert('最新版本已装置');
}
break;
case CodePush.SyncStatus.UPDATE_IGNORED:
{Alert.alert('更新已疏忽');
}
break;
case CodePush.SyncStatus.CHECKING_FOR_UPDATE:
{Alert.alert('正在查看更新');
}
break;
default:
break;
}
console.log(status);
},
() => {},
);
};
const clear = () => {CodePush.clearUpdates();
};
return (<SafeAreaView style={backgroundStyle}>
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<TouchableOpacity onPress={check}>
<Text>Check for updates</Text>
</TouchableOpacity>
<Text> 以后版本 1.1.1</Text>
<TouchableOpacity onPress={clear} style={{marginTop: 20}}>
<Text>clear updates</Text>
</TouchableOpacity>
{/** 校验图片 */}
{/* <Image source={testImg} style={{width: 100, height: 100}} /> */}
{/** 验证视频 */}
{/* <Video
source={consultant}
resizeMode="cover"
paused={false}
repeat
style={{width: 200, height: 200}}
/> */}
</View>
</SafeAreaView>
);
};
export default CodePush(App);
四、推送更新
首先,上传 jsbudle 包到 codepush,执行公布更新命令:
appcenter codepush release-react -a <ownerName>/<appName>
//example
appcenter codepush release-react -a <ownerName>/MyApp-iOS
appcenter codepush release-react -a <ownerName>/MyApp-Android
公布胜利会收到胜利的提醒。
在操作的过程中,遇到了一个推送 jsbudle 谬误。
appcenter codepush release-react -a 1256003290-qq.com/RNDemoIOS --plist-file-prefix "ios/orange"
/**error message */
/**Command 'codepush release-react -a 1256003290-qq.com/RNDemoIOS' failed with exception "Unable to find either of the following plist files in order to infer your app's binary version: "ios/reactnativecli/Info.plist", "ios/Info.plist". If your plist has a different name, or is located in a different directory, consider using either the "--plist-file" or "--plist-file-prefix" parameters to help inform the CLI how to find it." */
appcenter codepush release-react -a 1256003290-qq.com/RNDemoIOS
/** Command 'codepush release-react -a 1256003290-qq.com/RNDemoIOS' failed with exception "Unable to find either of the following plist files in order to infer your app's binary version: "ios/reactnativecli/Info.plist", "ios/Info.plist". If your plist has a different name, or is located in a different directory, consider using either the "--plist-file" or "--plist-file-prefix" parameters to help inform the CLI how to find it."*/
appcenter codepush release-react -a 1256003290-qq.com/RNDemoIOS -p"ios/orange/info.plist"
/** Command 'codepush release-react -a 1256003290-qq.com/RNDemoIOS -p ios/orange/info.plist' failed with exception "Unable to find either of the following pbxproj files in order to infer your app's binary version: "ios/reactnativecli.xcodeproj/project.pbxproj", "ios/project.pbxproj"."*/
发现怎么执行,codepush 都示意门路不对,找不到 info.plist。最初发现 codepush 去的包名是从 package.json 的 name,他会依照这个去找门路下的配置文件,我的包名恰好和我的项目名不统一,导致了问题。而后,批改 package 包名和我的项目名统一后就能够了。