參考了官方文檔 勺届,和Sean Chase 大神的Implementing Cordova Hot Code Push in Your Ionic App
最近做了熱更新缅疟,遇到了很多坑糙箍,記錄一下
在PS: 文章大部分是本人手工翻譯的盖矫,會(huì)有點(diǎn)兒僵硬大猛,有不對(duì)的地方請(qǐng)指出
使用的官方推薦的cordova-hot-code-push
[TOC]
運(yùn)行環(huán)境
- ionic --version : 4.0.5
- cordova --version: 8.0.0
注意事項(xiàng)
- 熱更新最好不要彈出框讓用戶選擇疼进,這樣很容易被蘋果爸爸拒絕兰迫。所以最好悄悄的自動(dòng)下載和更新信殊。詳情參考
- 打包時(shí)注意在
--prod
環(huán)境下執(zhí)行cordova-hcp build
Update workflow
開始操作之前,不妨看看ionic熱更新的原理汁果,畢竟磨刀不誤砍柴工涡拘,出了問(wèn)題可以更好的排查
流程圖如下:
- 用戶打開APP
- 初始化插件,同時(shí)在后臺(tái)線程啟動(dòng) update loader
- update loader 從
config.xml
中獲取config-file
(當(dāng)然也可以在代碼中或其他配置文件中配置)据德,然后從這個(gè)鏈接指定的url來(lái)加載JSON數(shù)據(jù)鳄乏。 然后拿加載的配置中release
版本與當(dāng)前installed的release
相比較。如果兩者不同棘利,就需要進(jìn)行下一步操作 - update loader 根據(jù) APP配置文件
cordova-hcp.json
中的content_url
來(lái)加載 manifest file橱野。 用它來(lái)比對(duì),相對(duì)于上個(gè)release善玫,有哪些更新了 - update loader 下載
content_url
地址對(duì)應(yīng)的 updated/new 中的所有文件 - 如果一切順利水援,將會(huì)發(fā)出更新已經(jīng)準(zhǔn)備完畢,可以安裝的通知
- 更新安裝后,app將會(huì)被重定向到APP的首頁(yè)
How web project files are stored and updated
每個(gè)Cordova 項(xiàng)目都有一個(gè) www
文件夾蜗元,用來(lái)存放所有的web文件誓斥。 當(dāng)執(zhí)行了 cordova build
,www
會(huì)被拷貝到平臺(tái)指定的www
文件夾下
- Android平臺(tái)拷貝到:
platforms/android/assets/www
- iS 平臺(tái)拷貝到:
platforms/ios/www
這些文件將隨APP一起打包许帐。 我們不能更新它們劳坑,因?yàn)樗鼈兪侵蛔x文件。因此成畦,首先要將這些文件寶貝到 external storage距芬。 因?yàn)椴幌朐诳截愡@些文件的時(shí)候阻塞用戶操作—將從打包的資源文件里顯示index page。當(dāng)以后的每一次啟動(dòng)/更新 ,都將從 external storage中加載index page
如果更新中包含有新添加的插件或者一些原生的代碼循帐,此時(shí)你需要在App Store發(fā)布新的版本框仔。
同時(shí),需要增加build version拄养。 在現(xiàn)在啟動(dòng)時(shí)离斩,熱更新插件會(huì)檢查build version是否改變,如果是瘪匿,就會(huì)重新安裝www
文件夾到external 文件夾中跛梗。
當(dāng)你開發(fā)app的時(shí)候,會(huì)感到迷惑: 做些改動(dòng)棋弥,啟動(dòng)app核偿,但是看到的還是舊內(nèi)容。現(xiàn)在你該恍然大明白了吧: 更新插件用的是external storage 中的web項(xiàng)目的version顽染⊙溃可以用如下方式重置緩存:
- 手動(dòng)卸載app,重裝
- 增加build version粉寞,強(qiáng)制插件重裝
www
文件夾尼荆。你可以更改config.xml中的
android-versionCode
或ios-CFBundleVersion
來(lái)達(dá)到該目的。 - 安裝 local development add-on唧垦, 這個(gè)插件可以幫你完成任務(wù)捅儒。它會(huì)自動(dòng)增加版本號(hào)。不過(guò)xcode9下业崖,它會(huì)報(bào)bug野芒,因?yàn)樗怯胹wift編譯的,需要你更改一些代碼双炕,會(huì)有點(diǎn)兒蛋疼狞悲。
也許你已經(jīng)注意到了,在www
文件中有一個(gè) chcp.json
文件妇斤,文件中有一個(gè) release
字段摇锋,這個(gè)是用來(lái)定義web內(nèi)容的version的丹拯。它是必須要有的字段,而且在每個(gè)release
中必須是惟一的荸恕。它有CLI生成乖酬,格式如:yyyy.MM.dd-HH.mm.ss
(i.e., 2015.09.01-13.30.35
).
更新插件會(huì)為每一個(gè)release
在external storage 創(chuàng)建一個(gè)同名的文件夾,同時(shí)把所有的web相關(guān)文件放入其中融求。它是項(xiàng)目的基地址咬像。這種方式可以解決如下幾個(gè)問(wèn)題:
- 文件緩存問(wèn)題。例如:在iOS中css文件被
UIWebView
緩存生宛,即使reload了index page县昂,新的樣式也不會(huì)被顯示。這時(shí)你必須殺掉APP陷舅,或者用一些奇淫技巧來(lái)改變css的url - 不會(huì)出現(xiàn)更新的內(nèi)容被已存在的內(nèi)容污染混淆倒彰,因?yàn)槊看?code>release更新用的是完全不同的文件夾
- 如果被污染了,我們還可以 rollback 到上一個(gè)版本
例如莱睁,假設(shè)當(dāng)前我們的APP運(yùn)行著 2015.12.01-12.01.33
版本待讳。 意味著:
- 所有的web內(nèi)容都存儲(chǔ)在
/sdcard/some_path/2015.12.01-12.01.33/www/
文件夾下。包括Cordova指定的文件 - index page顯示的是
/sdcard/some_path/2015.12.01-12.01.33/www/index.html
過(guò)了一陣仰剿,我們發(fā)布了新的版本: 2016.01.03-10.45.01
创淡。首先,更新插件會(huì)在設(shè)備上加載它酥馍,同時(shí):
- 一個(gè)新的文件夾在external storage 中創(chuàng)建:
/sdcard/some_path/2016.01.03-10.45.01/
. - 其中
update
文件夾被創(chuàng)建 :/sdcard/some_path/2016.01.03-10.45.01/update/
- 所有
chcp.manifest
中標(biāo)記的新的或變更的文件都將放置在update
文件夾中 - 這部分release會(huì)被下載到應(yīng)用內(nèi)部辩昆,并做好安裝準(zhǔn)備
當(dāng)安裝更新時(shí):
- 更新插件拷貝當(dāng)前版本(正顯示給用戶的)的
www
文件夾到新版本 release的文件夾。例如旨袒,拷貝所有/sdcard/some_path/2015.12.01-12.01.33/www/
下的文件到/sdcard/some_path/2016.01.03-10.45.01/www/
中 - 拷貝
update
目錄下的新文件,更新的文件以及配置文件到www
目錄中术辐。例如:/sdcard/some_path/2016.01.03-10.45.01/update/
->/sdcard/some_path/2016.01.03-10.45.01/www/
- 移除
/sdcard/some_path/2016.01.03-10.45.01/update/
目錄砚尽,我們已經(jīng)不再需要它了 - 從新release中加載index page:
/sdcard/some_path/2016.01.03-10.45.01/www/index.html
此時(shí)更新插件將會(huì)從新release目錄中加載index page,以前的release的將會(huì)作為備份以防萬(wàn)一辉词。
Step1 Create the Application
通過(guò)命令行創(chuàng)建新的ionic空白項(xiàng)目
ionic start chcp-example blank
cd .\chcp-example
Step2 Install Plugins
這里不用官方推薦的內(nèi)置服務(wù)器必孤,此處選擇更靈活的 lite-server
, 通過(guò)它提供的服務(wù)器來(lái)更新APP。 我們需要
將
lite-server
全局安裝并添加iOS和Android平臺(tái)支持
安裝 Cordova Hot Code Push plugin
安裝cordova-hot-code-push-cli
npm install -g lite-server
ionic cordova platform add android
ionic cordova plugin add cordova-hot-code-push-plugin
npm install -g cordova-hot-code-push-cli
Step3 Initializing the Hot Code Plugin Configuration
首先瑞躺,在命令行執(zhí)行 cordova-hcp init
按照提示輸入信息敷搪,不用擔(dān)心Amazon相關(guān)的信息,可以不用填寫
chcp-example>cordova-hcp init
Running init
Please provide: Enter project name (required): chcp-example
Please provide: Amazon S3 Bucket name (required for cordova-hcp deploy):
Please provide: Path in S3 bucket (optional for cordova-hcp deploy):
Please provide: Amazon S3 region (required for cordova-hcp deploy): (us-east-1)
Please provide: IOS app identifier:
Please provide: Android app identifier:
Please provide: Update method (required): (resume) start
Please provide: Enter full URL to directory where cordova-hcp build result will be uploaded: http://youserverip:3000/updates
Project initialized and cordova-hcp.json file created.
If you wish to exclude files from being published, specify them in .chcpignore
Before you can push updates you need to run "cordova-hcp login" in project directory
此時(shí)幢哨,你可以看到項(xiàng)目根目錄新生成了一個(gè)文件 cordova-hcp.json
赡勘,內(nèi)容大概如下:
{
"name": "chcp-example",
"ios_identifier": "",
"android_identifier": "",
"update": "start",
"content_url": "http://youserverip:3000/updates"
}
編輯 config.xml
文件,因?yàn)橐那牡淖詣?dòng)下載和安裝捞镰,所以要打開自動(dòng)下載和自動(dòng)安裝配置闸与。
<chcp>
<config-file url=”http://youserverip:3000/updates/chcp.json"/
<auto-download enabled=”true” />
<auto-install enabled=”true” />
</chcp>
Step4 Writing Application Logic
先在 /chcp-example/src/app/app.module.ts
文件中引入 HotCodePush
在 /chcp-example/src/app/app.component.ts
文件中添加更新邏輯毙替。
upgradeUrl = "your content file url"
constructor(
private hotCodePush: HotCodePush,
config: ConfigurationService,
) {
this.upgradeUrl = config.getValue<string>('upgradeUrl')
}
checkUpgrade() {
const options = {
'config-file': this.upgradeUrl,
}
this.log.debug(methodName, this.upgradeUrl)
this.hotCodePush.fetchUpdate(options).then(
data => {
this.log.debug(methodName, data)
this.installUpgrade()
},
error => {
this.log.debug(methodName, error)
},
)
}
installUpgrade() {
this.hotCodePush.installUpdate().then(
data => {
},
error => {
},
)
}
Step5 Build and Run in the Android/iOS
cordova prepare ios
cordova-hcp build
cordova run ios --device
Step6 Applying Updated Application Logic
讓APP在手機(jī)或模擬器上繼續(xù)running, 現(xiàn)在改動(dòng)home.html
文件中的文字
更改完畢后再次執(zhí)行如下命令:
cordova prepare ios
cordova-hcp build
更新后的代碼會(huì)在 www
文件夾下生成信息的文件
Step7 Providing the Updated Code
在與項(xiàng)目文件夾chcp-example
平級(jí)處創(chuàng)建 lite-server
的目錄chcp-example-server
,并創(chuàng)建子其目錄updates
— 這是用來(lái)放將要發(fā)布的代碼更新践樱。
用命令行來(lái)啟動(dòng)lite-server
chcp-example-server>lite-server
因?yàn)槭窃诒緳C(jī)測(cè)試厂画,需要將你的手機(jī)與電腦連接到同一個(gè)局域網(wǎng)中,然后手機(jī)的網(wǎng)絡(luò)代理設(shè)置成電腦的ip+端口號(hào)3000. iOS的具體設(shè)置
將 www
文件夾中的所有內(nèi)容拷貝到 updates
文件夾中拷邢。
回到手機(jī)上的APP袱院,然后手動(dòng)殺掉它。然后重新打開瞭稼,3秒內(nèi)白屏一閃, 改動(dòng)就可以看到了忽洛。
更多閱讀: