以下是基于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-Nativeappcenter 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//androidappcenter codepush deployment add -a <ownerName>/RNDemoAndroid Stagingappcenter 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" //增加这一行 applyfrom: "../../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 classimport codePush from "react-native-code-push";class MyApp extends Component { }MyApp = codePush(MyApp); //for hookimport 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-iOSappcenter 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包名和我的项目名统一后就能够了。