侧边栏壁纸
  • 累计撰写 23 篇文章
  • 累计创建 7 个标签
  • 累计收到 0 条评论
标签搜索

目 录CONTENT

文章目录

使用App Center 的CodePush(二)

爱喝酸梅汤的小猫咪
2023-05-30 / 0 评论 / 0 点赞 / 355 阅读 / 1,505 字

使用App Center 的CodePush(二)

Android和ios配置codepush

一、平台规则
(1).苹果App允许使用热更新Apple's developer agreement, 为了不影响用户体验,规定必须使用静默更新。
(2).Google Play不能使用静默更新,必须弹框告知用户App有更新。
(3).中国的android市场必须采用静默更新(如果弹框提示,App会被“请上传最新版本的二进制应用包”原因驳回)。

二、安装codepush
使用RN版本codepush

$ yarn add react-native-code-push
如果RN版本小于0.60  需要执行
react-native link react-native-code-push

三、Android集成
1.link之后,需要确保文件已配置

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')

android/app/build.gradle
dependencies {
    ...
    implementation project(':react-native-code-push')
    ...
}

MainApplication.java
@Override
protected List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(
    ...
    new CodePush(getResources().getString(R.string.CodePushDeploymentKey), getApplicationContext(), BuildConfig.DEBUG));
}        

2.设置部署的key
android/app/build.gradle

buildTypes {
        debug {
            resValue "string", "CodePushDeploymentKey", '""'
            resValue 'string', "CODE_PUSH_APK_BUILD_TIME", String.format("\"%d\"", System.currentTimeMillis())

        }
        release {
            signingConfig signingConfigs.release
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
            resValue "string", "CodePushDeploymentKey", '"xxx"'
            resValue 'string', "CODE_PUSH_APK_BUILD_TIME", String.format("\"%d\"", System.currentTimeMillis())
            ndk {
                abiFilters 'armeabi-v7a', 'arm64-v8a'
            }
        }
        releaseDevelop {
            signingConfig signingConfigs.release
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
            resValue "string", "CodePushDeploymentKey", '"xxx"'
            resValue 'string', "CODE_PUSH_APK_BUILD_TIME", String.format("\"%d\"", System.currentTimeMillis())
            matchingFallbacks = ['release']
            ndk {
                abiFilters 'armeabi-v7a', 'arm64-v8a'
                // architectures: 'armeabi-v7a', 'arm64-v8a', 'armeabi', 'x86', 'x86_64'
            }
        }
        releaseStaging {
            signingConfig signingConfigs.release
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"
            resValue "string", "CodePushDeploymentKey", '"xxx"'
            resValue 'string', "CODE_PUSH_APK_BUILD_TIME", String.format("\"%d\"", System.currentTimeMillis())
            matchingFallbacks = ['release']
            ndk {
                abiFilters 'armeabi-v7a', 'arm64-v8a'
                // architectures: 'armeabi-v7a', 'arm64-v8a', 'armeabi', 'x86', 'x86_64'
            }
        }
    }

可以看到,在这里有三个环境, develop,staging release=production
其中release,releaseDevelop,releaseStaging 是安卓规定的,不可修改。

四、ios配置
(1).打开Xcode项目,我在这里创建了三个Scheme,
分别是qingyulan,qingyulanStag,qingyulanPro
(2).选择 Build Settings 选项卡,点击工具栏的 + 并选择 Add User-Defined Setting
创建 CodePushDeploymentKey, 只更改release,同样的qingyulan和qingyulanStag都要更改

16681528836657

(3).打开项目的 Info.plist 文件,然后将CodePushDeploymentKey条目的值更改为$(CODEPUSH_KEY)

五、js代码
installMode参数
IMMEDIATE 立即更新
ON_NEXT_RESTART 下次App启动
ON_NEXT_RESUME 下次回到前台
ON_NEXT_SUSPEND 回到后台时间性,配合 minimumBackgroundDuration: 2 * 60 使用

(1).直接简易更新
App.js

import codePush from 'react-native-code-push'
const codePushOptions = {
  installMode: codePush.InstallMode.ON_NEXT_RESUME,
};
const App = () => {
    return <></>
}
export default codePush(codePushOptions)(App);

(2).手动更新
想对检查更新发生的时间进行细粒度控制,可以使用CodePush.sync() 随时调用
可以先关掉自动检查功能

import React from 'react';
import {View, StyleSheet,Button} from 'react-native';
import codePush from 'react-native-code-push';

const codePushOptions = { checkFrequency: codePush.CheckFrequency.MANUAL };
const App = () => {
  const checkForUpdate = () => {
    codePush.sync({
      updateDialog: true,
      installMode: codePush.InstallMode.IMMEDIATE,
    });
  };

  const clear = () => {
    codePush.clearUpdates();
  };

  return (
    <View style={styles.container}>
      <Button  onPress={checkForUpdate}>
        检查更新
      </AwesomeButton>
      <Button  onPress={clear}>
        清除更新
      </AwesomeButton>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
});

export default codePush(codePushOptions)(App);

(3).动态分配key
如果是服务器下发,动态分配key
创建一个文件
CodePushUtils.js

import { AppState, Platform, Alert } from 'react-native';
import codePush from 'react-native-code-push';
import RNConfigReader from 'react-native-config-reader';

const isDebugEnvironment = () => {
  const { scriptURL } = NativeModules.SourceCode;
  const devEvn = scriptURL.split('&')[1];
  return devEvn === 'dev=true';
};
const CodePushDeploymentKey = {
  ios: {
    development: '',
    staging: '',
    production: '',
  },
  android: {
    debug: '',
    release: '',
    releaseDevelop: '',
    releaseStaging: '',
  },
};

const getDeploymentKey = () => {
  const buildType = RNConfigReader.BUILD_TYPE;
  const deploymentKey =
    Platform.OS === 'android'
      ? CodePushDeploymentKey[Platform.OS][buildType]
      : isDebugEnvironment
      ? ''
      : CodePushDeploymentKey[Platform.OS][Config.APP_ENV];
  return deploymentKey;
};

const codePushStatusDidChange = async (syncStatus) => {
  switch (syncStatus) {
    case codePush.SyncStatus.CHECKING_FOR_UPDATE:
      // 0 - 正在查询CodePush服务器以进行更新。
      console.info('[CodePush] Checking for update.');
      break;
    case codePush.SyncStatus.AWAITING_USER_ACTION:
      // 1 - 有可用的更新,并且向最终用户显示了一个确认对话框。(仅在updateDialog使用时适用)
      console.info('[CodePush] Awaiting user action.');
      break;
    case codePush.SyncStatus.DOWNLOADING_PACKAGE:
      // 2 - 正在从CodePush服务器下载可用更新。
      console.info('[CodePush] Downloading package.');
      break;
    case codePush.SyncStatus.INSTALLING_UPDATE:
      // 3 - 已下载一个可用的更新,并将其安装。
      console.info('[CodePush] Installing update.');
      break;
    case codePush.SyncStatus.UP_TO_DATE:
      // 4 - 应用程序已配置的部署完全最新。
      console.info('[CodePush] App is up to date.');
      break;
    case codePush.SyncStatus.UPDATE_IGNORED:
      // 5 该应用程序具有可选更新,最终用户选择忽略该更新。(仅在updateDialog使用时适用)
      console.info('[CodePush] User cancelled the update.');
      break;
    case codePush.SyncStatus.UPDATE_INSTALLED:
      // 6 - 安装了一个可用的更新,它将根据 SyncOptions 中的 InstallMode指定在 syncStatusChangedCallback 函数返回后立即或在下次应用恢复/重新启动时立即运行。
      console.info('[CodePush] Installed update.');
      break;
    case codePush.SyncStatus.SYNC_IN_PROGRESS:
      // 7 - 正在执行的 sync 操作
      console.info('[CodePush] Sync already in progress.');
      break;
    case codePush.SyncStatus.UNKNOWN_ERROR:
      // -1 - 同步操作遇到未知错误。
      console.info('[CodePush] An unknown error occurred.');
      break;
  }
};

const codePushDownloadDidProgress = (progress) => {
  const curPercent = ((progress.receivedBytes / progress.totalBytes) * 100).toFixed(0);
  console.log('[CodePushUtils] Downloading Progress', `${curPercent}%`);
  // console.log(`${progress.receivedBytes} of ${progress.totalBytes} received.`);
};

const syncImmediate = async () => {
  const deploymentKey = getDeploymentKey();
  codePush.sync(
    {
      updateDialog: {
        // 是否显示更新描述
        appendReleaseDescription: true,
        // 更新描述的前缀。 默认为"Description"
        descriptionPrefix: '\n\n更新内容:\n',
        // 强制更新按钮文字,默认为continue
        mandatoryContinueButtonLabel: '立即更新',
        // 强制更新时的信息. 默认为"An update is available that must be installed."
        mandatoryUpdateMessage: '必须更新后才能使用',
        // 非强制更新时,按钮文字,默认为"ignore"
        optionalIgnoreButtonLabel: '稍后',
        // 非强制更新时,确认按钮文字. 默认为"Install"
        optionalInstallButtonLabel: '后台更新',
        // 非强制更新时,检查到更新的消息文本
        optionalUpdateMessage: '有新版本了,是否更新?',
        // Alert窗口的标题
        title: '更新',
      },
      deploymentKey,
      installMode: codePush.InstallMode.IMMEDIATE,
    },
    codePushStatusDidChange,
    codePushDownloadDidProgress,
  );
};

export const checkForUpdate = async () => {
  const deploymentKey = getDeploymentKey();
  const update = await codePush.checkForUpdate(deploymentKey);
  if (!update) {
    Alert.alert('提示', '已是最新版本');
  } else {
    syncImmediate();
  }
};

export const codePushSync = () => {
  checkForUpdate();
  //   AppState.addEventListener('change', (newState) => {
  //     newState === 'active' && syncImmediate();
  //   });
};

16681503026069

0
  • 0

评论区