React Native - react-native-code-push-热更新插件的使用[译文]

申浩广
2023-12-01

原文链接:react-native-code-push

关于CodePush在iOS端的简易使用可以看我这篇,觉得不错的话可以点个赞或关注。

React Native模块--CodePush

注意:本自述文件仅与我们插件的最新版本相关。 如果您使用的是旧版本,请切换到我们的GitHub仓库中的相关标签,以查看该特定版本的文档。

此插件为CodePush服务提供客户端集成,允许您轻松地向React Native应用程序添加动态更新体验。

它是如何工作的?

React Native应用程序由JavaScript文件和任何附带图像组成,这些图像由打包程序捆绑在一起并作为特定于平台的二进制文件(即.ipa.apk文件)的一部分进行分发。应用程序发布后,更新JavaScript代码(例如修复错误,添加新功能)或图像资源,需要您重新编译和重新分发整个二进制文件,当然,也包括相关商店的审核时间。

CodePush插件通过保持你的JavaScriptimages与发布到CodePush服务器的更新同步,使得用户可以立即获得改进后的产品。通过这种方式,您的应用可以获得离线移动体验的好处,以及一旦可用,就可以获得侧面加载更新的“类网络”的敏捷性。这是双赢的!

为了确保您的最终用户始终拥有应用程序的正常版本,CodePush插件会维护以前更新的副本,以便在您意外推送包含崩溃的更新时,它可以自动回滚。这样,您可以放心,在您有机会回滚服务器版本之前,您发布的新版本不会影响到用户。这是一个双赢的局面!

注意:任何与本机代码相关的产品更改(例如,修改AppDelegate.m / MainActivity.java文件,添加新插件)都无法通过CodePush分发,因此必须通过相应的商店进行更新。

入门

根据 "getting started" 设置你的CodePush帐户,在应用程序的根目录中执行以下命令,即可在你的React Native应用程序中使用CodePush-ifying

npm install --save react-native-code-push
复制代码

与所有其他React Native插件一样,iOS和Android的集成体验也不同,因此请根据您要定位的平台执行以下设置步骤。 请注意,如果您要定位两个平台,建议为每个平台创建单独的CodePush应用程序。

如果您想了解其他项目如何与CodePush集成,您可以查看社区提供的优秀示例应用程序。 此外,如果您想快速熟悉CodePush + React Native,您可以查看由Bilal Budhani和/或Deepak Sisodiya制作的精彩入门视频。

注意:本指南假定您已使用react-native init命令初始化React Native项目。 截至2017年3月,命令create-react-native-app也可用于初始化React Native项目。 如果使用此命令,请在项目的主目录中运行npm run eject,以获得与react-native init创建的项目非常相似的项目。

接下来继续安装原生模块

插件使用

下载和链接CodePush插件,并从CodePush获取到正确的JS捆绑包后,接下来唯一要做的事就是向你的应用添加必要的代码,以控制以下流程:

  1. 何时(以及多久)检查一次更新?(例如,在App启动后,以某个固定时间间隔,定期地响应设置页面按钮的点击)
  2. 当有更新时,如何将其呈现给用户?

最简单的方法是使用“CodePush-ify”应用程序的根组件。 为此,您可以选择以下两个方法中的一个:

  • 方法1:使用codePush高阶组件包裹您的根组件:

    import codePush from "react-native-code-push";
    
    class MyApp extends Component {
    }
    
    MyApp = codePush(MyApp);
    复制代码
  • 方法2:使用ES7装饰器语法:

    注意:Babel 6.x待定提案更新尚不支持ES7装饰器语法。 您可能需要通过安装和使用babel-preset-react-native-stage-0来启用它。

    import codePush from "react-native-code-push";
    
    @codePush
    class MyApp extends Component {
    }
    复制代码

默认情况下,CodePush将检查每个应用程序启动时的更新。 如果有可用的更新,它将以静默方式下载,并在下次重新启动应用程序时安装(由最终用户或操作系统明确安装),这可确保用户体验。 如果必需更新,则会立即安装,确保用户尽快获得最新版本。

如果您希望应用程序更快地发现更新,您还可以选择在每次应用程序从后台恢复时与CodePush服务器同步。

let codePushOptions = { checkFrequency: codePush.CheckFrequency.ON_APP_RESUME };

class MyApp extends Component {
}

MyApp = codePush(codePushOptions)(MyApp);
复制代码

或者,如果您希望对检查发生的时间进行细粒度控制(例如按下按钮或定时器间隔),您可以随时使用所需的SyncOptions调用CodePush.sync(),也可以选择通过指定一个手动检查频率(checkFrequency:)来关闭CodePush的自动检查。

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);
复制代码

如果想要显示确认更新的对话框(立即安装),请在安装可用更新时进行配置(例如强制立即重启)或以任何其他方式自定义更新体验,请参阅codePush()API参考有关如何调整此默认行为的信息。

注意:如果您使用的是ReduxRedux Saga,您也可以使用react-native-code-push-saga模块,该模块允许您以更简单/更惯用的方式自定义何时调用同步。

商店指南的合规性

虽然Google Play和内部分布式应用程序(例如EnterpriseFabricHockeyApp)对如何使用CodePush发布更新没有任何限制,但在应用程序中集成解决方案之前,您应该注意iOS App Store及其相应指南中的细致规则。

第3.3.2段,自2015年以来,Apple开发者计划许可协议完全允许对JavaScriptassets进行无线更新 - 在最新版本(20170605)中,这一规则更为广泛:

解释执行的代码可以下载到应用程序,但只有符合以下规则代码: (a)不会通过提供与提交给App Store的应用程序的预期和广告目的不一致的特性或功能来改变应用程序的主要目的。 (b)不为其他代码或应用程序创建商店或店面。 (c)不绕过操作系统的签名,沙箱或其他安全功能。

CodePush允许您完全遵从这些规则,只要您推送的更新不会使您的产品与提交App Store审核时的功能明显不同。

为了进一步遵守Apple的指导原则,我们建议App Store分发的应用程序在调用sync时不启用updateDialog选项,因为在App Store Review Guidelines中,它写道:

Apps must not force users to rate the app, review the app, download other apps, or other similar actions in order to access functionality, content, or use of the app.

这不一定是updateDialog的问题,因为它不会强迫用户下载新版本,但如果你决定要显示更新,那么至少你应该知道这些规则。

发布更新

一旦您的应用程序配置并分发给您的用户,并且您已经进行了一些JS和/或assets更改,就可以立即发布它们了! 最简单(和推荐)的方法是在CodePush CLI中使用release-react命令,它将处理并捆绑您的JavaScriptassets文件并将更新发布到CodePush服务器。

在它最基本的形式中,此命令只需要两个参数:您的应用程序名称和要捆绑更新的平台(iosandroid)。

code-push release-react <appName> <platform>

code-push release-react MyApp-iOS ios
code-push release-react MyApp-Android android
复制代码

release-react命令启用了这样一个简单的工作流,因为它提供了许多合理的默认值(例如,生成一个发布包,假设您的应用程序在iOS上的条目文件是index.ios.jsindex.js)。但是,所有这些默认值都可以自定义,以便在必要时提供增量灵活性,这使其非常适合大多数情况。

 # Release a mandatory update with a changelog
code-push release-react MyApp-iOS ios -m --description "Modified the header color"

 # Release an update for an app that uses a non-standard entry file name, and also capture
 # the sourcemap file generated by react-native bundle
code-push release-react MyApp-iOS ios --entryFile MyApp.js --sourcemapOutput ../maps/MyApp.map

 # Release a dev Android build to just 1/4 of your end users
code-push release-react MyApp-Android android --rollout 25% --dev true

 # Release an update that targets users running any 1.1.* binary, as opposed to
 # limiting the update to exact version name in the build.gradle file
code-push release-react MyApp-Android android --targetBinaryVersion "~1.1.0"
复制代码

CodePush客户端支持差异更新,因此即使您在每次更新时发布JS包和assets,您的最终用户也只会下载实际所需的文件。该服务自动处理此问题,以便您可以专注于创建真棒应用程序,我们负责优化用户的下载。

有关release-react命令如何工作的更多详细信息,以及它公开的各种参数,请参阅CLI文档。 此外,如果您更愿意自己处理react-native bundle命令,因此需要比release-react更灵活的解决方案,请参阅release命令以获取更多详细信息。

如果您遇到任何问题,或有任何问题/意见/反馈,您可以在Reactiflux上的#code-push频道中ping我们,发送电子邮件给我们和/或查看下面的故障排除详情

注意:CodePush更新应在调试模式以外的模式下进行测试。 在调试模式下,React Native应用程序总是下载由packager生成的JS包,因此CodePush下载的JS包不适用。

多部署 测试

在我们的入门文档中,我们说明了如何使用特定的部署密钥配置CodePush插件。 但是,为了有效地测试您的版本,您必须利用首次创建CodePush应用程序时(或您可能已创建的任何自定义部署)自动生成的暂存(Staging)生产部署(Production)。 这样,您在验证更新功能的时候就不会对真实用户进行发布操作。

注意:我们的客户端回滚功能可以使已安装奔溃版本的用户进行版本回滚,并且服务器端回滚(即代码推送回滚)允许您阻止其他用户在识别后安装错误版本。 但是,如果您可以防止错误的更新发布,那么显然会更好。

利用阶段(Staging)生产部署(Production),您可以实现以下工作流程(随意自定义!):

  1. 使用code-push release-react命令(或代码推送版本,如果您需要更多控制)向您的Staging部署发布CodePush更新
  2. 运行应用程序的临时/测试版本,从服务器同步更新,并验证它是否按预期工作
  3. 使用code-push promote命令将测试版本从Staging升级到Production
  4. 运行应用程序的生产/发布版本,从服务器同步更新并验证它是否按预期工作

*注意:只要你想,您甚至可以选择执行“分阶段部署”作为#3的一部分,这可以让您通过更新降低额外的潜在风险(例如,您在#2中的测试是否触摸了所有可能的设备 /条件?)只对一部分用户提供生产更新(例如: code-push promote <APP_NAME> Staging Production -r 20%)。 然后,在等待一段合理的时间来查看是否有任何崩溃报告或客户反馈后,您可以通过code-push patch <APP_NAME> Production -r 100%将其扩展到整个受众。*

您会注意到上述步骤涉及应用程序的“阶段构建”“生产构建”。 如果您的构建过程已经为每个“环境”生成了不同的二进制文件,那么您不需要再进行任何阅读,因为更换CodePush部署密钥就像处理应用程序使用其他服务(例如Facebook)的特定于环境的配置一样。 但是,如果您正在寻找有关如何设置构建过程以适应此目的的示例(包括演示项目),请参阅以下部分,具体取决于您的应用所针对的平台:

动态部署分配

上一节说明了如何利用多个CodePush部署,以便在更新发布给用户之前,有效地测试您的更新内容。 但是,由于该工作流静态地将部署分配嵌入到实际二进制文件中,因此临时构建生产构建只会同步该部署的更新内容。在许多情况下,这是足够的,因为您只希望您的团队,客户,利益相关者等与您的预生产版本同步,因此,他们只需要知道如何与该版本同步构建。但是,如果您希望能够进行A / B测试,或者为某些用户提供应用程序的早期访问权限,那么能够在运行时将特定用户(或受众)动态地置于特定部署中将非常有用。

为了实现这种工作流,您需要做的就是在调用codePush方法时指定特定用户同步的部署密钥。 指定后,此键将覆盖应用程序的Info.plist(iOS)MainActivity.java(Android)文件中提供的默认键。 这允许您生成临时或生产构建,也可以根据需要动态“重定向”。

// Imagine that "userProfile" is a prop that this component received
// which includes the deployment key that the current user should use.
codePush.sync({ deploymentKey: userProfile.CODEPUSH_KEY });
复制代码

有了这样的变化后,现在只需选择应用程序如何为当前用户配置正确的部署密钥。 在实践中,通常有两种解决方案:

  1. 将更改部署的功能开放给用户。例如,您的设置页面可能会有一个切换按钮以启用“测试版”的访问权限。 如果您不在乎预生产更新的内容被得知,并且您的某些用户可能希望根据自己的意愿选择使用最新(并且可能有错误)的更新(有点像Chrome渠道)。 但是,此解决方案将决策权交给您的用户,这无法帮助您透明地执行A / B测试。
  2. 使用额外的元数据注释用户的服务器端配置文件,标明与其同步的部署。 默认情况下,您的应用只能使用二进制嵌入密钥,但在用户通过身份验证后,您的服务器可以选择将其“重定向”到其他部署,这样您就可以根据需要逐步将某些用户或组放置在不同的部署中。您甚至可以选择将服务器响应存储在本地存储中,以使其成为新的默认值。 如何将密钥与用户的配置文件一起存储完全取决于您的身份验证解决方案(例如Auth0,Firebase,自定义DB + REST API),但这通常非常简单。

注意:如果需要,您还可以实施混合解决方案,允许最终用户在不同部署之间切换,同时还允许您的服务器覆盖该决策。 这样,您就拥有了“部署解决方案”的层次结构,可确保您的应用程序能够自行更新,用户可以通过获得最新内容的访问权限来获得最新体验,但您也有能力根据需要对用户进行A / B测试。

由于我们建议使用分段(Staging)部署进行更新的预发布测试(如上一节所述),因此使用它来对用户执行A / B测试是不必要的,与此相反,您应该通过允许提前访问的形式进行(如上面选项#1中所述)。 因此,我们建议您充分利用自定义应用部署,以便您可以根据自己的需求对用户进行细分。 例如,您可以创建长期甚至一次性部署,向其发布应用的变体,然后将某些用户放入其中,以便了解他们的参与方式。

// #1) Create your new deployment to hold releases of a specific app variant
code-push deployment add [APP_NAME] test-variant-one

// #2) Target any new releases at that custom deployment
code-push release-react [APP_NAME] ios -d test-variant-one
复制代码

注意:从一个部署“切换”到另一个部署的用户数,被纳入到部署中的“安装度量”中报告的总用户数。例如,如果您的生产部署当前报告的用户总数为1,但您将该用户动态切换为阶段部署,则生产部署将报告0个总用户,而阶段部署将报告1(刚刚切换的用户)。 即使在使用基于运行时的部署重定向解决方案的情况下,这种行为可以让你准确地跟踪您的版本使用情况。

转载请注明出处。

转载于:https://juejin.im/post/5c7e30e4e51d4541c53730dc

 类似资料: