警告
React Native CodePush不支持新的体系结构。为了从0.76开始使用此插件,在React本机版本上使用此插件,您需要选择退出新体系结构。
注意:此读数仅与我们的插件的最新版本有关。如果您使用的是旧版本,请切换到我们的GitHub存储库上的相关标签,以查看该特定版本的文档。
该插件为CodePush服务提供了客户端集成,使您可以轻松地在React Antive应用程序中添加动态更新体验。
React Native应用程序由JavaScript文件和任何随附的图像组成,这些图像由Metro Bundler捆绑在一起,并作为平台特定二进制(即.ipa
或.apk
文件)的一部分分发。发布该应用后,更新JavaScript代码(例如,进行错误修复,添加新功能)或图像资产,要求您重新编译并重新分配整个二进制文件,当然,其中包括与商店相关的任何评论时间您正在出版。
CodePush插件通过将JavaScript和图像与您发布到CodePush服务器的更新同步,有助于立即在最终用户面前进行产品改进。这样,您的应用将获得离线移动体验的好处,以及一旦可用的“类似网络”的敏捷性。这是双赢!
为了确保最终用户始终具有应用程序功能的功能版本,CodePush插件将维护上一个更新的副本,以便如果您不小心推动更新(包括崩溃),则可以自动回滚。这样,您可以放心,您的新发现的释放敏捷性不会导致用户在您有机会退回服务器之前被阻止。这是双赢!
注意:任何触摸本机代码的产品更改(例如修改AppDelegate.m
/ MainActivity.java
文件,添加新插件)都不能通过CodePush分发,因此必须通过适当的商店进行更新。
我们尽力保持插件与以前版本的React本地版本的向后兼容性,但是由于平台的性质以及发行版之间的破坏变化的存在,您可能需要使用CodePush的特定版本插件以支持您使用的React本机的确切版本。下表概述了哪些CodePush插件版本正式支持各自的React本机版本:
反应本地版本 | 支持CodePush版本 |
---|---|
<0.14 | 不支持 |
V0.14 | v1.3 (引入Android支持) |
V0.15-V0.18 | V1.4-V1.6 (引入iOS资产支持) |
V0.19-V0.28 | V1.7-V1.17 (引入Android资产支持) |
V0.29-V0.30 | V1.13-V1.17 (RN重构本机托管代码) |
V0.31-V0.33 | V1.14.6-V1.17 (RN重构本机托管代码) |
V0.34-V0.35 | V1.15-V1.17 (RN重构本机托管代码) |
V0.36-V0.39 | V1.16-V1.17 (RN重构简历处理程序) |
V0.40-V0.42 | v1.17 (RN重构iOS标头文件) |
V0.43-V0.44 | v2.0+ (RN重构Uimanager依赖性) |
V0.45 | v3.0+ (RN重构实例管理器代码) |
V0.46 | v4.0+ (RN重构JS捆绑加载器代码) |
V0.46-V0.53 | v5.1+ (RN删除了JS模块的未使用的注册) |
V0.54-V0.55 | v5.3+ (Android Gradle插件3.x集成) |
V0.56-V0.58 | v5.4+ (Android工具的RN升级版本) |
V0.59 | v5.6+ (RN重构JS捆绑加载器代码) |
V0.60-V0.61 | v6.0+ (RN迁移到自动联系) |
V0.62-V0.64 | v6.2+ (RN删除了livereload) |
V0.65-V0.70 | v7.0+ (RN更新的iPhone-target-version) |
V0.71 | v8.0+ (RN移至反应生长剂量 - plugin) |
注意:低于v5.7.0的react-native-code-push
版将在不久的将来停止工作。您可以在我们的文档中找到更多信息。
我们努力响应新的RN版本,但它们偶尔会打破我们。我们将使用每个RN版本更新此图表,以便用户可以检查以查看我们的“官方”支持是什么。
当使用React Antive Assets系统(即使用require("./foo.png")
语法)时,以下列表代表了一组核心组件(和Props),该集合支持具有通过CodePush更新其引用的图像和视频:
成分 | 道具 |
---|---|
Image | source |
MapView.Marker (需要反应型映射 >=O.3.2 ) | image |
ProgressViewIOS | progressImage , trackImage |
TabBarIOS.Item | icon , selectedIcon |
ToolbarAndroid (反应天然0.21.0+) | actions[].icon , logo , overflowIcon |
Video | source |
以下列表代表了当前不支持其资产正在通过CodePush更新的组件(和Props),因为它们依赖于静态图像和视频(即使用{ uri: "foo" }
语法):
成分 | 道具 |
---|---|
SliderIOS | maximumTrackImage , minimumTrackImage , thumbImage , trackImage |
Video | source |
随着新的核心组件的发布,支持参考资产,我们将更新此列表,以确保用户知道使用CodePush可以更新的确切更新。
注意:CodePush在源道具中使用require
时仅与视频组件一起使用。例如:
< Video source = { require ( "./foo.mp4" ) } / >
遵循通用的“入门”指令以设置CodePush帐户,您可以通过从应用程序的root目录中运行以下命令来开始CodePush-yift codepush:
npm install --save react-native-code-push
与所有其他React Native插件一样,iOS和Android的集成体验也不同,因此,根据您要定位的平台执行以下设置步骤。请注意,如果您针对两个平台,建议为每个平台创建单独的CodePush应用程序。
如果您想查看其他项目如何与CodePush集成,可以查看社区提供的出色示例应用程序。此外,如果您想快速熟悉CodePush + React Native,可以查看Bilal Budhani和/或Deepak Sisodiya制作的令人敬畏的入门视频。
注意:本指南假设您使用了react-native init
命令来初始化您的React本机项目。截至2017年3月,命令create-react-native-app
也可以用于初始化React Native项目。如果使用此命令,请在项目的主目录中运行npm run eject
以获取一个与react-native init
创建的项目非常相似的项目。
然后继续安装本机模块
通过下载和链接的CodePush插件,并且您的应用询问CodePush从哪里获得合适的JS捆绑包,剩下的唯一的是将必要的代码添加到您的应用程序中以控制以下策略:
何时(多久)检查更新? (例如,应用程序启动,响应在设置页面中单击按钮,以某个固定的间隔定期)
当有更新时,如何将其展示给最终用户?
做到这一点的最简单方法是“ CodePush-yify”您的应用程序的根组件。为此,您可以选择以下两个选项之一:
选项1:将root组件与codePush
高阶组件包装:
对于类组件
import codePush from "react-native-code-push" ;
class MyApp extends Component {
}
MyApp = codePush ( MyApp ) ;
用于功能组件
import codePush from "react-native-code-push" ;
let MyApp : ( ) => React$Node = ( ) => {
}
MyApp = codePush ( MyApp ) ;
选项2:使用ES7装饰器语法:
注意:Babel 6.x待定提案更新中尚未支持装饰人员。您可能需要通过安装和使用babel-preset-reaction-native stage-0来启用它。
对于类组件
import codePush from "react-native-code-push" ;
@ codePush
class MyApp extends Component {
}
用于功能组件
import codePush from "react-native-code-push" ;
const MyApp : ( ) => React$Node = ( ) => {
}
export default codePush ( MyApp ) ;
默认情况下,CodePush将检查每个应用程序启动的更新。如果有可用的更新,它将被静止下载,并在下次重新启动应用程序时(由最终用户明确或OS明确)安装,这确保了最终用户的侵入性最少。如果强制性更新是强制性的,则将立即安装,以确保最终用户尽快获取。
如果您希望您的应用程序更快地发现更新,则每当应用程序从后台恢复时,也可以选择与CodePush服务器同步。
对于类组件
let codePushOptions = { checkFrequency : codePush . CheckFrequency . ON_APP_RESUME } ;
class MyApp extends Component {
}
MyApp = codePush ( codePushOptions ) ( MyApp ) ;
用于功能组件
let codePushOptions = { checkFrequency : codePush . CheckFrequency . ON_APP_RESUME } ;
let MyApp : ( ) => React$Node = ( ) => {
}
MyApp = codePush ( codePushOptions ) ( MyApp ) ;
另外,如果您需要对检查发生时(例如按钮或SyncOptions
间隔CodePush.sync()
进行细粒度控制手动checkFrequency
:
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参考有关如何调整此默认行为的信息。
注意:如果您使用的是Redux和Redux传奇,则可以使用React-Native-Native-push-saga模块,该模块可以在以可能更简单/更惯用的方式调用sync
时自定义。
Android Google Play和iOS App Store具有相应的指南,在将CodePush解决方案集成到应用程序中之前,您应该知道规则。
设备和网络滥用主题的第三段描述,限制了通过Google Play更新机制以外的任何方法更新源代码。但是,此限制不适用于更新JavaScript捆绑包。
该限制不适用于在虚拟机中运行的代码,并且对Android API的访问有限(例如WebView或浏览器中的JavaScript)。
这完全允许CodePush更新JS捆绑包,并且无法更新本机代码部分。
第3.3.2段以来,自2015年的苹果开发人员计划许可协议以来,完全允许执行JavaScript和Assets的无线更新 - 以及在其最新版本(20170605)中可下载的最新版本(20170605),此裁决甚至更广泛:
解释的代码可以下载到应用程序中,但只有在此类代码之后才下载:(a)不会通过提供与提交给应用程序的应用程序的预期和广告目的不一致的功能或功能来改变应用程序的主要目的商店,(b)不会为其他代码或应用程序创建商店或店面,并且(c)不会绕过OS的签名,沙箱或其他安全功能。
CodePush允许您完全合规遵守这些规则,只要您推出的更新不会显着偏离其原始App Store批准的意图即可。
为了进一步符合Apple的准则,我们建议应用程序分布的应用程序在调用sync
时不会启用updateDialog
选项,因为在App Store评论指南中,请写下:
应用程序不得强制用户对应用程序进行评分,查看应用程序,下载其他应用程序或其他类似操作,以访问应用程序的功能,内容或使用。
updateDialog
不一定是这种情况,因为它不会迫使用户下载新版本,但是至少如果您决定展示该裁定,则应意识到该裁决。
将应用程序配置并分发给用户,并且您进行了一些JS或资产更改,就该发布它们了。释放它们的推荐方法是使用App Center CLI中的release-react
命令,该命令将捆绑您的JavaScript文件,资产文件,并将更新发布到CodePush服务器上。
注意:在开始发布更新之前,请通过运行appcenter login
命令登录到App Center。
在其最基本的形式中,此命令仅需要一个参数:您的所有者名称 +“/” +应用程序名称。
appcenter codepush release-react -a < ownerName > / < appName >
appcenter codepush release-react -a < ownerName > /MyApp-iOS
appcenter codepush release-react -a < ownerName > /MyApp-Android
release-react
命令启用了如此简单的工作流程,因为它提供了许多明智的默认值(例如,假设您在iOS上的应用程序的输入文件是index.ios.js
或index.js
)。但是,所有这些默认值都可以自定义,以便在必要时允许增量灵活性,这使其非常适合大多数情况。
# Release a mandatory update with a changelog
appcenter codepush release-react -a < ownerName > /MyApp-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
appcenter codepush release-react -a < ownerName > /MyApp-iOS --entry-file MyApp.js --sourcemap-output ../maps/MyApp.map
# Release a dev Android build to just 1/4 of your end users
appcenter codepush release-react -a < ownerName > /MyApp-Android --rollout 25 --development 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
appcenter codepush release-react -a < ownerName > /MyApp-Android --target-binary-version " ~1.1.0 "
CodePush客户端支持差异更新,因此,即使您在每个更新中都释放JS捆绑包和资产,您的最终用户也只会实际下载所需的文件。该服务会自动处理此操作,以便您可以专注于创建很棒的应用程序,我们可以担心优化最终用户下载。
有关release-react
命令的工作方式以及暴露的各种参数的更多详细信息,请参阅CLI文档。此外,如果您希望自己处理运行react-native bundle
命令,因此,您需要一个比release-react
更灵活的解决方案,请参阅release
命令以获取更多详细信息。
如果您遇到任何问题,或者有任何疑问/注释/反馈,则可以在deartiflux上的#code-push频道中ping我们,通过电子邮件发送给我们和/或查看下面的故障排除详细信息。
注意:CodePush更新应以除调试模式以外的模式进行测试。在调试模式下,React Native App始终下载Packager生成的JS捆绑包,因此CodePush下载的JS捆绑包不适用。
在我们入门文档中,我们说明了如何使用特定的部署密钥配置CodePush插件。但是,为了有效地测试您的发行版,至关重要的是,您必须在首次创建CodePush应用程序(或您可能创建的任何自定义部署)时利用自动生成的Staging
和Production
部署。这样,您永远不会向最终用户发布更新,使您无法验证自己。
注意:我们的客户端回滚功能可以在安装导致崩溃的版本后解除阻止用户,并且服务器端回滚(即appcenter codepush rollback
)允许您防止一旦确定,就可以防止其他用户安装不良版本。但是,如果您可以防止错误的更新首先被广泛发布,那显然更好。
利用Staging
和Production
部署可以使您获得以下工作流程(随时自定义!)::
使用appcenter codepush release-react
command(或appcenter codepush release
(如果需要更多控制),将CodePush更新发布到您的Staging
部署中
运行应用程序的登台/beta构建,同步服务器的更新,然后验证它的工作原理
使用appcenter codepush promote
Command促进经过Staging
的发行版Production
运行您的应用程序的生产/发布构建,同步服务器的更新并验证其工作原理
注意:如果您想采取更谨慎的方法,您甚至可以选择作为#3的一部分执行“舞台推出”,这使您可以通过更新来减轻额外的潜在风险(例如,在#2中进行测试可能的设备/条件?)仅使您的一部分用户可用生产更新(例如appcenter codepush promote -a <ownerName>/<appName> -s Staging -d Production -r 20
)。然后,在等待合理的时间来查看是否出现任何崩溃报告或客户反馈之后,您可以通过运行appcenter codepush patch -a <ownerName>/<appName> 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 } ) ;
随着该更改的到位,现在只是选择应用程序如何确定当前用户的正确部署密钥的问题。实际上,通常有两个解决方案:
揭露一种可随时更改部署的用户可见机制。例如,您的设置页面可能具有启用“ beta”访问的切换。如果您不关心预生产更新的隐私,并且您的电力用户可能希望早些时候(又可能是有可能发生故障)的更新(有点像Chrome Channels) )。但是,该解决方案将决定掌握在用户手中,这无助于您执行A/B的测试可以透明地测试。
用另一块元数据来注释用户的服务器端配置文件,以表明他们应该同步的部署。默认情况下,您的应用程序只能使用二进制键的密钥,但是在用户进行身份验证后,您的服务器可以选择将它们“重定向”到其他部署,这使您可以根据需要将某些用户或组递增,将其放置在不同的部署中。您甚至可以选择将服务器响应存储在本地存储中,以使其成为新的默认值。如何将密钥与用户配置文件一起存储完全取决于您的身份验证解决方案(例如Auth0,Firebase,自定义DB + REST API),但通常很琐碎。
注意:如果需要,您还可以实现一个混合解决方案,该解决方案允许您的最终用户在不同部署之间切换,同时还允许您的服务器覆盖该决定。这样,您将拥有“部署解决方案”的层次结构,可确保您的应用程序能够更新自动范围,您的最终用户可以通过尽早访问位来感到有益,但是您也有能力根据需要对用户进行A/B测试。
由于我们建议使用Staging
部署进行更新的预发行测试(如上一节所述),因此使用它用于对用户进行A/B测试,而不是允许早期 -访问(如上面的选项#1中所述)。因此,我们建议充分利用自定义应用程序部署,以便您可以分割用户,但是可以满足您的需求。例如,您可以创建长期甚至一次性的部署,将应用程序的变体释放到其中,然后将某些用户放入其中以查看它们的参与度。
// #1) Create your new deployment to hold releases of a specific app variant
appcenter codepush deployment add - a < ownerName > / <appName> test-variant-one
// #2) Target any new releases at that custom deployment
appcenter codepush release - react - a < ownerName > / <appName> -d test-variant-one
注意:您部署的“安装指标”中报告的用户数量将考虑到已经从一个部署到另一个部署的用户。例如,如果您的Production
部署当前报告总共1个用户,但是您将该用户动态切换到Staging
,则Production
部署将报告0个用户,而Staging
将报告1(刚刚切换的用户)。即使在使用基于运行时的部署重定向解决方案的情况下,这种行为也使您可以准确跟踪发布的采用率。
React Native社区慷慨地创建了一些很棒的开源应用程序,可以作为即将开始的开发人员的示例。以下是也使用CodePush的OSS React Antive应用程序的列表,因此可以用来查看其他人如何使用该服务:
此外,如果您想开始使用React Native + CodePush,并且正在寻找一个很棒的入门套件,则应查看以下内容:
注意:如果您使用CodePush开发了一个React Native应用程序,那也是开源的,请告诉我们。我们很想将其添加到此列表中!
sync
方法包含大量诊断开箱即用的诊断,因此,如果您在使用它时遇到问题,那么首先尝试的最好的方法是检查应用程序的输出日志。这将告诉您是否正确配置了该应用程序(例如插件可以找到您的部署密钥吗?),如果该应用程序能够到达服务器,如果发现可用更新,如果已成功下载/安装了更新,等等。我们希望继续改善日志记录,以尽可能直观/全面,因此,如果您发现它令人困惑或缺少任何东西,请告诉我们。
查看这些日志的最简单方法是为每个命令添加标志--debug
。这将输出被过滤到CodePush消息的日志流。这使得可以轻松识别问题,而无需使用特定于平台的工具,或者通过潜在的大量日志进行涉水。
此外,如果您对它们更舒适,也可以使用任何特定于平台的工具来查看CodePush日志。简单启动Chrome DevTools控制台,Xcode Console(ios),OS X控制台(ios)和/或ADB LogCat(Android),并查找带有[CodePush]
的消息。
请注意,默认情况下,React Native Logs在发行版中的iOS上被禁用,因此,如果要在版本构建中查看它们,则需要对AppDelegate.m
文件进行以下更改:
添加#import <React/RCTLog.h>
语句。对于RN <V0.40使用: #import "RCTLog.h"
将以下语句添加到application:didFinishLaunchingWithOptions
方法:
RCTSetLogThreshold (RCTLogLevelInfo);
现在,您可以在iOS或Android上以调试或发布模式看到CodePush日志。如果检查日志没有提供问题的指示,请参阅以下常见问题以获取其他解决方案:
问题 /症状 | 可能的解决方案 |
---|---|
汇编错误 | 双检查您的React Antial版本是否与您使用的CodePush版本兼容。 |
iOS模拟器中呼叫sync 或checkForUpdate 时网络超时 /挂起 | 尝试通过选择Simulator -> Reset Content and Settings.. 菜单项,然后重新运行您的应用程序。 |
致电sync 或checkForUpdate 时,服务器响应404 | 仔细检查您添加到Info.plist (ios), build.gradle (android)的部署键,或者您正在传递到sync / checkForUpdate ,实际上是正确的。您可以运行appcenter codepush deployment list <ownerName>/<appName> --displayKeys 以查看应用程序部署的正确键。 |
未发现更新 | 仔细检查运行应用程序的版本(例如1.0.0 )与您在将更新发布到CodePush时指定的版本。此外,请确保您要发布与应用程序配置为同步的相同部署。 |
重新启动后不显示更新 | 如果您不在应用程序启动(例如在根组件的componentDidMount 中)调用sync ,则需要在应用程序开始时明确调用notifyApplicationReady ,否则,该插件会认为您的更新失败并将其倒退。 |
我已经发布了iOS的更新,但我的Android应用也显示了一个更新,它会破坏 | 确保每个平台都有不同的部署键,以便正确接收更新 |
我发布了新的更新,但没有反映更改 | 确保您以除调试以外的模式运行应用程序。在调试模式下,React Native App始终下载Packager生成的JS捆绑包,因此CodePush下载的JS捆绑包不适用。 |
在使用iOS模拟器运行应用程序时,找不到JS捆绑包 | 默认情况下,React Anitive在与模拟器上运行时不会生成您的JS捆绑包。因此,如果您使用[CodePush bundleURL] 并针对iOS模拟器,则可能会得到nil 结果。此问题将在RN 0.22.0中解决,但仅用于发布版本。您可以立即通过本地进行此更改来解除这种情况。 |
除了能够使用CodePush CLI“手动”发布更新外,我们认为创建一个可重复且可持续的解决方案很重要,以诱人地为您的应用程序提供更新。这样,您和/或您的团队就足够简单,可以创建和维护执行敏捷部署的节奏。为了协助设置基于CodePush的CD管道,请参阅以下各种CI服务器的集成:
此外,如果您想了解完整的移动CI/CD工作流程的更多详细信息,其中包括CodePush,请查看Zeemee Engineering团队的出色文章。
该模块作为其NPM软件包的一部分,将其*.d.ts
文件import
使用打字稿。但是,在大多数情况下,此行为应仅开箱即用,如果您将es6
指定为tsconfig.json
文件中target
或module
编译器选项的值,则只需确保您还设置moduleResolution
dounder to node
。这样可以确保打字稿编译器将在node_modules
中查看导入模块的类型定义。否则,当尝试导入react-native-code-push
模块时,您将会遇到以下错误: error TS2307: Cannot find module 'react-native-code-push'
。
该项目采用了Microsoft开源的行为代码。有关更多信息,请参见《行为守则常见问题守则》或与其他问题或评论联系[email protected]。