Appcenter Code Push

RN code push 接入步骤

codepush cli已被弃用,使用appcenter cli接入code push官方文档

App center 配置

注册App center 账户官网

在RNProject根目录执行,全局安装appcenter-cli
npm install -g appcenter-cli

登录appcenter
npx appcenter login

命令执行完网页会弹出Authentication token

复制token到命令行进行登录

由于rn产出的android包与ios包一般都是有区别的,因此需要新建两个app,一般默认命名都是类似于XXProject-Android,XXProject-IOS

使用命令行添加项目

npx appcenter apps create -p React-Native -o Android -d XXProject-Android -r Production -n xxproject-android-url-name --description 'Android示例项目'

npx appcenter apps create --platform React-Native --os iOS --display-name XXProject-IOS --release-type Production --name xxproject-ios-url-name --description 'IOS示例项目'

使用网页添加项目

集成Code Push

在RNProject根目录中使用以下命令中集成CodePush
npm install --save react-native-code-push

使用Code Push

点击按钮创建默认的两个发布环境:预发布环境Staging,与生产环境Production

发布环境如需要使用命令,则先查看现有app
npx appcenter apps list

执行新建部署

appcenter codepush deployment add -a name/xxproject-android-url-name Staging
appcenter codepush deployment add -a name/xxproject-android-url-name Production

Android 端接入

接入react-native-code-push组件。在RNProject/android/settings.gradle 文件末尾,添加

include ':react-native-code-push'
project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')

在RNProject/android/app/build.gradle中添加

apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"

在MainApplication添加

...
// 1. 引入CodePush包
import com.microsoft.codepush.react.CodePush;
...

public class MainApplication extends Application implements ReactApplication {

    // 3. 构建CodePushReactNativeHost实例
    private final CodePushReactNativeHost mReactNativeHost = new CodePushReactNativeHost(this);

    // 2. 添加内部类,继承ReactNativeHost,并实现ReactInstanceHolder接口
    private static class CodePushReactNativeHost extends ReactNativeHost implements ReactInstanceHolder{

        protected CodePushReactNativeHost(Application application) {
            super(application);
        }

        @Override
        public boolean getUseDeveloperSupport() {
            return BuildConfig.DEBUG;
        }

        @Override
        protected List<ReactPackage> getPackages() {
            @SuppressWarnings("UnnecessaryLocalVariable")
            List<ReactPackage> packages = new PackageList(this).getPackages();
            return packages;
        }

        // 4. 重写getJSBundleFile方法
        @Nullable
        @Override
        protected String getJSBundleFile() {
            return CodePush.getJSBundleFile();
        }

        @Override
        protected String getJSMainModuleName() {
            return "index";
        }
    }


    private final ReactNativeHost mNewArchitectureNativeHost = new MainApplicationReactNativeHost(this);

    @Override
    public ReactNativeHost getReactNativeHost() {
        if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
            return mNewArchitectureNativeHost;
        } else {
            return mReactNativeHost;
        }
    }

    @Override
    public void onCreate() {
    // 5. 设置setReactInstanceHolder
    CodePush.setReactInstanceHolder((ReactInstanceHolder) mReactNativeHost);
        super.onCreate();
        ...
    }
    ...
}

获取key
使用命令行方式

npx appcenter codepush deployment list -a ownername/RNProject-Android -k

网页中获取
将所需部署环境的key放到strings.xml

 <resources>
     ...
     <string moduleConfig="true" name="CodePushDeploymentKey">DeploymentKey</string>
 </resources>

服务器 URL - 用于指定 CodePush 服务器 URL。 默认值:"https://codepush.appcenter.ms/" 通过将路径添加到名称为strings.xml 来重写 CodePushServerUrl。CodePush 会自动获取此属性,并将使用此路径发送请求

<string moduleConfig="true" name="CodePushServerUrl">https://yourcodepush.server.com</string>

部署key的环境需要与以下部署命令的一致,RNProject中,默认debug版使用Staging,release版使用Production)。
更推荐的做法,是不使用strings.xml定义,而将key使用gradle配置

android {
    ...
    buildTypes {
        debug {
            ...
            // CodePush更新不应在开发时使用,因为codepush会覆盖rn开发包。但是CodePush sdk会在所有模式下都去检查更新,因此需要提供key。XXProject中,直接使用Staging环境的key
            resValue "string", "CodePushDeploymentKey", '""'
            ...
        }
        releaseStaging {
            ...
            // 预发布环境Staging的key,XXProject由于历史原因,直接使用了debug
            resValue "string", "CodePushDeploymentKey", '"<INSERT_STAGING_KEY>"'
            // matchingFallbacks表示找不到的依赖使用release类似配置
            matchingFallbacks = ['release']
            ...
        }
        release {
            ...
            // 正式环境Production的key
            resValue "string", "CodePushDeploymentKey", '"<INSERT_PRODUCTION_KEY>"'
            ...
        }
    }
    ...
}

React Native配置

接入Android与IOS原生SDK后,需要配置react native以确定codepush更新检查与安装时机

主模块接入codepush

//设置检查更新的频率
//ON_APP_RESUME APP恢复到前台的时候
//ON_APP_START APP开启的时候
//MANUAL 手动检查
let codePushOptions = { checkFrequency: codePush.CheckFrequency.MANUAL }

App = codePush(codePushOptions)(App)

codePushOptions可以不传,默认行为为app启动时检查更新,有更新时静默下载,并在再次冷启动时安装更新。

React Native 客户端 SDK API 参考

checkFrequency:检查更新的时机

  • 默认为CodePush.CheckFrequency.ON_APP_START,app冷启动时
  • CodePush.CheckFrequency.ON_APP_RESUME,app回到前台时,如home键、跳到别的app再回来时
  • CodePush.CheckFrequency.MANUAL,不自动检查更新,需要使用codePush.sync()手动检查。特别注意,手动模式时,如果调用codePush检查更新(checkForUpdate)的时机不是在app start时,必须在加载前notifyAppReady以防止更新重启之后jsbundle回滚
  componentWillMount() {
    // 更新重启之后,防止回滚
    CodePush.notifyAppReady()
  }

installMode:应用更新的时机

  • 默认为codePush.InstallMode.ON_NEXT_RESTART, 下次冷启动时应用更新
  • codePush.InstallMode.ON_NEXT_RESUME ,app回到前台时应用更新
  • codePush.InstallMode.ON_NEXT_SUSPEND ,页面退到后台minimumBackgroundDuration(默认0)秒后,再次回到前台时应用更新
  • codePush.InstallMode.IMMEDIATE ,检查到更新后,立即应用更新

自定义更新时机

如果业务需求在有更新时,弹窗提示更新,就需要用到两个常用的函数CodePush.checkForUpdate和CodePush.sync

class App extends Component {
  ...
  const codePushOptions = {
    // 设置检查更新的频率
    // ON_APP_RESUME APP恢复到前台的时候
    // ON_APP_START APP开启的时候
    // MANUAL 手动检查
    // 1、设定为手动更新
    checkFrequency: CodePush.CheckFrequency.MANUAL
  };

  syncCodePush() {
    // 3、应用更新
    CodePush.sync({
      // 安装模式
      // ON_NEXT_RESUME 下次恢复到前台时
      // ON_NEXT_RESTART 下一次重启时
      // IMMEDIATE 马上更新
      installMode: CodePush.InstallMode.IMMEDIATE,
      // 后台30秒以上才更新
      // minimumBackgroundDuration: 30
      // 不要使用原生对话框!!!!,需要的话自行配置,2022/3/9新版android codepush源码CodePushDialog直接在非主线程mqt_native_modules上show
      // updateDialog:true
    });
  }

  componentWillMount() {
    // 更新重启之后,防止回滚
    CodePush.notifyAppReady();
    // 在加载完了可以允许重启
    CodePush.disallowRestart();
  }

  componentDidMount() {
    that = this
    //在加载完了可以允许重启
    CodePush.allowRestart();
    // 2、检查是否有更新
    CodePush.checkForUpdate().then((update)=>{
      if(!update){
        console.log("The app is up to date!");
      } else {
        // 自定义弹窗提示新版本,或其他操作,此处省略 
        that.syncCodePush()
      }
    });
  }
  ...
}

CodePush.checkForUpdate(deploymentKey: String = null, handleBinaryVersionMismatchCallback: (update: RemotePackage) => void): Promise<RemotePackage>

  • 参数deploymentKey可以指定检测不同的发布环境key,可用于实现灵活配置付费版等功能的更新
  • 参数handleBinaryVersionMismatchCallback,处理更新版本返回,比如现在app的jsb版本是1.0.0,但是查询到新的jsb更新是1.0.1版本的,此回调可做此类可选项处理
  • 返回的Promise函数null时,无更新或更新对当前版本app不可用,否则返回RemotePackage对象:
    downloadUrl——包可供下载的 URL;
    download (downloadProgressCallback?: Function) : Promise<LocalPackage>——下载更新,downloadProgressCallback用于回调进度,返回LocalPackage的Promise用于安装

CodePush.sync(options?: SyncOptions, syncStatusChangedCallback?: SyncStatusChangedCallback, downloadProgressCallback?: DownloadProgressCallback, handleBinaryVersionMismatchCallback?: HandleBinaryVersionMismatchCallback): Promise
参考React Native 客户端 SDK API 参考

发布与更新包

使用命令发布更新

npx appcenter codepush release-react -a ownername/xxproject-android-url-name -d Staging -t 0.0.1

发布更新命令详解

参考文档

App Center 官网

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,830评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,992评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,875评论 0 331
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,837评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,734评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,091评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,550评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,217评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,368评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,298评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,350评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,027评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,623评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,706评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,940评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,349评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,936评论 2 341

推荐阅读更多精彩内容