文档(v9)
代码集成

安装配置完成后,确定应用编译顺利通过,下面我们来进行代码集成。

极简快速集成

我们从 v8.x 版本开始提供极简的三行式集成(老版本只能使用自定义集成方式):

import { Platform } from "react-native";
import { simpleUpdate } from "react-native-update";
import _updateConfig from "./update.json";
const { appKey } = _updateConfig[Platform.OS];
 
// 整个应用的根组件,class 或函数组件都可以
class App extends Component {
  // 这是个空的示例,请替换为你自己的根组件
}
 
// 对根组件使用simpleUpdate方法封装后导出
export default simpleUpdate(App, {
  appKey,
  onPushyEvents: ({ type, data }) => {
    // 热更成功或报错的事件回调
    // 可上报自有或第三方数据统计服务
  },
});

此方式默认在 App 启动,以及从后台切换到前台时触发更新检查,弹出提示的内容也固定。如需自定义触发时机,以及修改界面提示等,请参考下面的自定义集成方式。

自定义集成

获取 appKey

检查更新时必须提供你的appKey,这个值保存在update.json中,并且根据平台不同而不同。你可以用如下的代码获取:

import { Platform } from "react-native";
 
import _updateConfig from "./update.json";
const { appKey } = _updateConfig[Platform.OS];

如果你不使用 pushy 命令行,也可以从网页端查看到两个应用 appKey,并根据平台的不同来选择。

检查更新、下载更新

异步函数checkUpdate可以检查当前版本是否需要更新:

const info = await checkUpdate(appKey);

返回的info有三种情况:

  1. {expired: true}:该应用原生包已过期(三种情况:1. 主动设置为过期状态,2. 主动删除,3. 从未上传),开发者应该在 pushy 控制台添加一个更新下载链接,并自行提示用户下载。

  2. {upToDate: true}:当前已经更新到最新,无需进行更新。

  3. {update: true}:当前有新版本可以更新。info 的namedescription字段可以用于提示用户,而metaInfo字段则可以根据你的需求自定义其它属性(如是否静默更新、是否强制更新等等),具体用法可参考场景实践。另外还有几个字段,包含了补丁包的下载地址等。 pushy 会首先尝试耗费流量更少的更新方式。将info对象传递给downloadUpdate方法作为参数即可。

const hash = await downloadUpdate(
  info,
  // 下载回调为可选参数,从v5.8.3版本开始加入
  {
    onDownloadProgress: ({ received, total }) => {
      // 已下载的字节数, 总字节数
      console.log(received, total);
    },
  }
);

downloadUpdate方法从v5.8.3版本开始新增接受第二个可选参数,为下载进度的回调函数(onDownloadProgress)。可根据回调参数自行设计进度的展示。

切换版本

downloadUpdate的返回值是一个 hash 字符串,它是当前热更新版本的唯一标识。

你可以使用switchVersion(hash)函数立即切换版本(此时应用会立即重新加载),或者选择调用 switchVersionLater(hash),让应用在下一次启动的时候再加载新的版本。

首次启动、回滚

在每次更新完毕后的首次启动时,isFirstTime常量会为true。你必须在应用退出前合适的任何时机,调用markSuccess,否则应用下一次启动的时候将会进行回滚操作。这一机制称作“反触发”,这样当你应用启动初期即遭遇问题的时候,也能在下一次启动时恢复运作。

你可以通过isFirstTime来获知这是当前版本的首次启动,也可以通过isRolledBack来获知应用刚刚经历了一次回滚操作。你可以在此时给予用户合理的提示。

以上提及的所有 api 的说明文档可在这里查看。

完整的示例

import React, { Component } from "react";
 
import {
  StyleSheet,
  Platform,
  Text,
  View,
  Alert,
  TouchableOpacity,
  Linking,
} from "react-native";
 
import {
  isFirstTime,
  isRolledBack,
  packageVersion,
  currentVersion,
  checkUpdate,
  downloadUpdate,
  switchVersion,
  switchVersionLater,
  markSuccess,
  downloadAndInstallApk,
  onPushyEvents,
} from "react-native-update";
 
import _updateConfig from "./update.json";
const { appKey } = _updateConfig[Platform.OS];
onPushyEvents(({ type, data }) => {
  // 热更成功或报错的事件回调
  // 可上报自有或第三方数据统计服务
});
 
export default class MyProject extends Component {
  state = {
    received: 0,
    total: 0,
  };
  componentDidMount() {
    if (isFirstTime) {
      // 必须调用此更新成功标记方法
      // 否则默认更新失败,下一次启动会自动回滚
      markSuccess();
      console.log("更新完成");
    } else if (isRolledBack) {
      console.log("刚刚更新失败了,版本被回滚.");
    }
  }
  doUpdate = async (info) => {
    try {
      const hash = await downloadUpdate(info, {
        onDownloadProgress: ({ received, total }) => {
          this.setState({
            received,
            total,
          });
        },
      });
      if (!hash) {
        return;
      }
      Alert.alert("提示", "下载完毕,是否重启应用?", [
        {
          text: "是",
          onPress: () => {
            switchVersion(hash);
          },
        },
        { text: "否" },
        {
          text: "下次启动时",
          onPress: () => {
            switchVersionLater(hash);
          },
        },
      ]);
    } catch (err) {
      Alert.alert("更新失败", err.message);
    }
  };
  checkUpdate = async () => {
    if (__DEV__) {
      // 开发模式不支持热更新,跳过检查
      return;
    }
    let info;
    try {
      info = await checkUpdate(appKey);
    } catch (err) {
      Alert.alert("更新检查失败", err.message);
      return;
    }
    if (info.expired) {
      Alert.alert("提示", "您的应用版本已更新,点击确定下载安装新版本", [
        {
          text: "确定",
          onPress: () => {
            // downloadUrl 需要在后台设置中自行配置
            if (info.downloadUrl) {
              // apk可直接下载安装
              if (
                Platform.OS === "android" &&
                info.downloadUrl.endsWith(".apk")
              ) {
                // 此方法还需要额外的配置,请参考
                // https://pushy.reactnative.cn/docs/api#async-function-downloadandinstallapk-url-ondownloadprogress-
                downloadAndInstallApk({
                  url: info.downloadUrl,
                  onDownloadProgress: ({ received, total }) => {
                    this.setState({
                      received,
                      total,
                    });
                  },
                });
              } else {
                Linking.openURL(info.downloadUrl);
              }
            }
          },
        },
      ]);
    } else if (info.upToDate) {
      Alert.alert("提示", "您的应用版本已是最新.");
    } else if (info.update) {
      Alert.alert(
        "提示",
        "检查到新的版本" + info.name + ",是否下载?\n" + info.description,
        [
          {
            text: "是",
            onPress: () => {
              this.doUpdate(info);
            },
          },
          { text: "否" },
        ]
      );
    }
  };
  render() {
    const { received, total } = this.state;
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>欢迎使用热更新服务</Text>
        <Text style={styles.instructions}>
          这是版本一 {"\n"}
          当前原生包版本号: {packageVersion}
          {"\n"}
          当前热更新版本Hash: {currentVersion || "(空)"}
          {"\n"}
        </Text>
        <Text>
          下载进度:{received} / {total}
        </Text>
        <TouchableOpacity onPress={this.checkUpdate}>
          <Text style={styles.instructions}>点击这里检查更新</Text>
        </TouchableOpacity>
      </View>
    );
  }
}
 
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "#F5FCFF",
  },
  welcome: {
    fontSize: 20,
    textAlign: "center",
    margin: 10,
  },
  instructions: {
    textAlign: "center",
    color: "#333333",
    marginBottom: 5,
  },
});

现在,你的应用已经可以通过 pushy 服务检查版本并进行更新了。下一步,你可以开始尝试发布应用包和版本,请参阅发布热更新