最近在研究熱更新的相關(guān)內(nèi)容,看了很多文檔,或多或少都有不少的坑沒有解釋清楚,無法走通,就自己總結(jié)了下相關(guān)的集成和使用流程,親測可用
關(guān)于CodePush集成之前的準(zhǔn)備工作,React native的集成和使用見文檔 http://www.itdecent.cn/p/142d153a0377
CodePush簡介
CodePush 是微軟提供的一套用于熱更新 React Native 和 Cordova 應(yīng)用的服務(wù)。
CodePush 是提供給 React Native 和 Cordova 開發(fā)者直接部署移動應(yīng)用更新給用戶設(shè)備的云服務(wù)。CodePush 作為一個中央倉庫,開發(fā)者可以推送更新 (JS, HTML, CSS and images),應(yīng)用可以從客戶端 SDK 里面查詢更新。CodePush 可以讓應(yīng)用有更多的可確定性,也可以讓你直接接觸用戶群。在修復(fù)一些小問題和添加新特性的時候,不需要經(jīng)過二進(jìn)制打包,可以直接推送代碼進(jìn)行實時更新。
一、安裝CodePush
- 安裝codepush客戶端
npm install -g code-push-cli
檢查是否安裝成功: code-push -v
查看歷史版本: npm view npm versions
如果一直安裝失敗,考慮用 cnpm install -g code-push-cli安裝,未安裝cnpm使用 cnpm install -g rnpm 安裝
2.注冊codePush賬號,獲取access key
code-push register 在打開的瀏覽器中完成注冊工作,會得到一串鑰匙串,保存下來
3.使用獲取到的access key進(jìn)行登錄
code-push login
成功后你的 session 文件將會寫在 /Users/你的用戶名/.code-push.config
相關(guān)命令:
npm install -g code-push-cli //安裝codepush客戶端
code-push register //注冊codepush賬號
code-push login //登錄
code-push loout //注銷
code-push access-key ls //列出登陸的token
code-push access-key rm <accessKye> //刪除某個 access-key
4.在CodePush服務(wù)器注冊app
code-push app add <appName>
或者 code-push app add <appName> <os> <platform>
例:code-push app add appName 或 code-push app add appName ios react-native
注冊成功之后會返回一套 deployment key 給你,生產(chǎn)環(huán)境和開發(fā)環(huán)境的
PS:相關(guān)命令
code-push app add 在賬號里面添加一個新的 App
code-push app remove 或者 rm 在賬號里移除一個 App
code-push app rename 重命名一個存在 App
code-push app list 或則 ls 列出賬號下面的所有 App
code-push app transfer 把 App 的所有權(quán)轉(zhuǎn)移到另外一個賬號
二、項目中集成CodePush
找到項目中的node_modules文件夾,進(jìn)入到與該文件夾同級的路徑下,執(zhí)行指令
npm install --save react-native-code-push
此時會在node_modules文件夾中生成react-native-code-push文件夾
CodePush官方提供RNPM、CocoaPods與手動三種在iOS項目中集成CodePush的方式,任選其一,如果不行可以嘗試另外的方法
1.RNPM
找到項目中的node_modules文件夾,進(jìn)入到與該文件夾同級的路徑下,通過命令自動在 iOS 中鏈接、配置好設(shè)置:
** React Native v0.27 版本開始使用 : react-native link react-native-code-push
** 版本低于 v0.27 的 React Native使用 : rnpm link react-native-code-push
如果需要安裝 RNPM : npm i -g rnpm
按提示填入獲取到的deployment key - Staging 完成配置
2.CocoaPods
在Podfile文件中添加:
pod 'CodePush', :path => '../node_modules/react-native-code-push'//路徑根據(jù)自己的文件目錄修改
安裝 : pod install
需要繼續(xù)完成配置
1.打開調(diào)用main.jsbundle文件的地方,一般在AppDelegate.m 文件,并引入 CodePush 頭文件:
#import <CodePush/CodePush.h>
2.找到以下代碼行:
jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
3.將其替換為此行:
jsCodeLocation = [CodePush bundleURL];
此更改將應(yīng)用配置為始終加載應(yīng)用的 jsbundle的最新版本 。在通過 CodePush 推送更新前,他只會使用應(yīng)用程序編譯的文件。但是,在通過 CodePush 推送更新后,它將返回最近安裝更新的位置。
注意:
該 bundleURL 方法假定應(yīng)用程序的 jsbundle 為默認(rèn)的 main.jsbundle 。如果你更改了應(yīng)用程序 jsbundle 的文件名,則只需調(diào)用方法 bundleURLForResource:或 bundleURLForResource:withExtension: 以覆蓋默認(rèn)的行為。
關(guān)于jsbundle文件的生成可以參考文檔 http://www.itdecent.cn/p/142d153a0377
建議使用 DEBUG 宏預(yù)處理器,實現(xiàn)在開發(fā)模式下調(diào)試 和 在生產(chǎn)模式下使用 CodePush 熱更新之間動態(tài)切換。具體代碼如下:
NSURL *jsCodeLocation;
ifdef DEBUG
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
else
jsCodeLocation = [CodePush bundleURL];
endif
4.找到項目的 Project欄 -> info
在 Configurations 節(jié)點下面點擊 +,選擇 Duplicate “Release”,輸入Staging
再點擊 +,選擇 Duplicate “Debug”,輸入Production
5.選擇 Build Settings 單擊Levels與搜索框之間的 “+” (如果沒有發(fā)現(xiàn),記得拉伸xcode的寬度,可能因為寬度不夠隱藏了), 然后選擇添加 User-Defined Setting,輸入 CODEPUSH_KEY
展開CODEPUSH_KEY,配置對應(yīng)的Deployment Key,對應(yīng)值為 CodePush CLI注冊app時申請獲得的Deployment Key,可以通過code-push deployment ls <appName> -k 查詢
6.在應(yīng)用程序Info.plist文件中添加 CodePushDeploymentKey,對應(yīng)值為 $(CODEPUSH_KEY)
3.手動集成
1.在 Xcode 中打開應(yīng)用項目,將工程文件目錄下 "../node_modules/react-native-code-push/ios" 中的 "CodePush.xcodeproj" 文件拖動到 Xcode 工程節(jié)點 Libraries 里;
2.在 Xcode 中選擇項目節(jié)點,并選擇項目配置的 "Build Phases" 選項卡;
從 "Libraries/CodePush.xcodeproj/Products" 拖動 "libCodePush.a" 到項目"Build Phases" 的 "Link Binary With Libraries";
單擊 "Link Binary With Libraries" 列表下方的加號,添加 "libz.tbd";
3. 需要繼續(xù)完成配置,步驟與上述CocoaPods配置步驟一致
三、設(shè)置更新控制策略
在使用CodePush更新你的應(yīng)用之前需要,先配置一下更新控制策略,即:
- 什么時候檢查更新?(在APP啟動的時候?在設(shè)置頁面添加一個檢查更新按鈕?)
- 什么時候可以更新,如何將更新呈現(xiàn)給終端用戶?
最簡單的方式是在根component中進(jìn)行上述策略控制。
import codePush from 'react-native-code-push'
class MyApp extends Component {
componentDidMount() {
codePush.sync({updateDialog:{title:"An update is available!"}});
}
}
如果可以進(jìn)行更新,CodePush會在后臺靜默地將更新下載到本地,等待APP下一次啟動的時候應(yīng)用更新,以確保用戶看到的是最新版本。注意修改MyApp為項目名。
如果更新是強(qiáng)制性的,更新文件下載好之后會立即進(jìn)行更新。
如果你期望更及時的獲得更新,可以在每次APP從后臺進(jìn)入前臺的時候去主動的檢查更新:
在應(yīng)用的根component的componentDidMount中添加如下代碼:
import codePush from 'react-native-code-push'
class MyApp extends Component {
componentDidMount() {
AppState.addEventListener("change", (newState) => {
newState === "active" && codePush.sync();
});
}
}
或者:
let codePushOptions = { checkFrequency: codePush.CheckFrequency.ON_APP_RESUME };
class MyApp extends Component {
}
MyApp = codePush(codePushOptions)(MyApp);
注意修改MyApp為項目名。
四、發(fā)布更新
1.簡單方式:(將打包與發(fā)布兩個命令合二為一,建議使用)
基本用法:
code-push release-react <appName> <platform>
eg:
code-push release-react ReactNativeTestDemo ios # iOS版
code-push release-react ReactNativeTestDemo android #Android版
命令后面可以帶上各種參數(shù)來控制更新的版本、是否強(qiáng)制更新等等,更多參數(shù)可以在終端輸入code-push release-react進(jìn)行查看
具體可參照官方文檔:https://www.npmjs.com/package/code-push-cli
遇到的問題:
[Error] Unable to find either of the following plist files in order to infer your app's binary version: "ios/ReactNativeTestDemo/Info.plist", "ios/Info.plist". If your plist has a different name, or is located in a different directory, consider using either the "--plistFile" or "--plistFilePrefix" parameters to help inform the CLI how to find it.
解析:找不到plist文件所在位置,通過添加參數(shù)來解決 -p代表info.plist文件
--mandatory 代表強(qiáng)制更新
code-push release-react ReactNativeTestDemo ios -p "./ReactNativeTestDemo/Info.plist" --mandatory
**注意info.plist文件里的版本號要與需要熱更新的app版本一致
2.復(fù)雜方式:先需要打包才能發(fā)布
首先將 js 與 圖片資源 打包成 bundle,再通過命令 code-push release 發(fā)布
打包bundle
cd 到工程目錄,新增 bundles 文件夾
$ mkdir bundles
運行命令打包
$ react-native bundle --platform <平臺> --entry-file <啟動文件> --bundle-output <打包js輸出文件> --assets-dest <資源輸出目錄> --dev <是否調(diào)試>
eg:
$ react-native bundle --platform ios --entry-file index.ios.js --bundle-output ./bundles/index.ios.bundle --dev false
發(fā)布更新
$ code-push release <應(yīng)用名稱> <bundle所在目錄> <對應(yīng)的應(yīng)用版本> -d <更新環(huán)境> --des <更新描述說明> -m <是否強(qiáng)制更新>
eg:
$ code-push release CodePushDemo-ios ./bundles/index.ios.bundle 1.0.0 -d Production --des "更新描述說明" -m true
<對應(yīng)的應(yīng)用版本> 為 app 的版本號,不是 CodePush 所更新的 js 的版本號
-d <更新環(huán)境> 默認(rèn)值是更新 staging 環(huán)境的
3.可以通過code-push deployment ls <appName> -k 查詢發(fā)布狀態(tài)
五.其他命令
1.code-push 賬號管理 相關(guān)命令
# 注冊
$ code-push register
# 登錄
$ code-push login
$ code-push login http://服務(wù)器IP:3000
# 注銷
$ code-push logout
# 當(dāng)前登錄賬號
$ code-push whoami
# 列出登錄的 token
$ code-push access-key ls
# 刪除某個 key 值
$ code-push access-key rm <accessKye>
2.code-push app 相關(guān)命令
# 添加 app
$ code-push app add <appName>
# 重命名 app
$ code-push app rename <appName> <newAppName>
# 移除 app
$ code-push app remove <appName>
# 列出所有 app
$ code-push app list
# app 所有權(quán)轉(zhuǎn)移
$ code-push app transfer <appName> <newOwnerEmail>
3.code-push deployment 相關(guān)命令
# 添加部署環(huán)境
$ code-push deployment add <appName> <deploymentName>
# 重命名部署環(huán)境名稱
$ code-push deployment rename <appName> <deploymentName> <newDeploymentName>
# 刪除部署環(huán)境
$ code-push deployment rm <appName> <deploymentName>
# 列出應(yīng)用的所有部署環(huán)境
$ code-push deployment ls <appName>
# 列出應(yīng)用的所有部署環(huán)境及 key
$ code-push deployment ls <appName> -k
# 查看歷史版本(Production 或者 Staging)
$ code-push deployment history <appName> <deploymentName>
# 清除某個部署環(huán)境的更新記錄
$ code-push deployment clear <appName> <deploymentName>
- 更多命令,可以在終端輸入 code-push 進(jìn)行查看
參考:
http://www.itdecent.cn/p/19f23d66286f
http://www.itdecent.cn/p/7e6c3edce494
http://www.itdecent.cn/p/9e3b4a133bcc