警告
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]。