Ionic 热更新实践笔记

参考了官方文档 ,和Sean Chase 大神的Implementing Cordova Hot Code Push in Your Ionic App

最近做了热更新,遇到了很多坑,记录一下

在PS: 文章大部分是本人手工翻译的,会有点儿僵硬,有不对的地方请指出

使用的官方推荐的cordova-hot-code-push

[TOC]

运行环境

  • ionic --version : 4.0.5
  • cordova --version: 8.0.0

注意事项

  • 热更新最好不要弹出框让用户选择,这样很容易被苹果爸爸拒绝。所以最好悄悄的自动下载和更新。详情参考
  • 打包时注意在 --prod环境下执行cordova-hcp build

Update workflow

开始操作之前,不妨看看ionic热更新的原理,毕竟磨刀不误砍柴工,出了问题可以更好的排查

流程图如下:

图片来源官方文档
  1. 用户打开APP
  2. 初始化插件,同时在后台线程启动 update loader
  3. update loader 从config.xml 中获取 config-file (当然也可以在代码中或其他配置文件中配置),然后从这个链接指定的url来加载JSON数据。 然后拿加载的配置中 release 版本与当前installed的release相比较。如果两者不同,就需要进行下一步操作
  4. update loader 根据 APP配置文件cordova-hcp.json中的content_url 来加载 manifest file。 用它来比对,相对于上个release,有哪些更新了
  5. update loader 下载 content_url 地址对应的 updated/new 中的所有文件
  6. 如果一切顺利,将会发出更新已经准备完毕,可以安装的通知
  7. 更新安装后,app将会被重定向到APP的首页

How web project files are stored and updated

每个Cordova 项目都有一个 www文件夹,用来存放所有的web文件。 当执行了 cordova buildwww会被拷贝到平台指定的www文件夹下

  • Android平台拷贝到: platforms/android/assets/www
  • iS 平台拷贝到: platforms/ios/www

这些文件将随APP一起打包。 我们不能更新它们,因为它们是只读文件。因此,首先要将这些文件宝贝到 external storage。 因为不想在拷贝这些文件的时候阻塞用户操作—将从打包的资源文件里显示index page。当以后的每一次启动/更新 ,都将从 external storage中加载index page

如果更新中包含有新添加的插件或者一些原生的代码,此时你需要在App Store发布新的版本。

同时,需要增加build version。 在现在启动时,热更新插件会检查build version是否改变,如果是,就会重新安装www文件夹到external 文件夹中。

当你开发app的时候,会感到迷惑: 做些改动,启动app,但是看到的还是旧内容。现在你该恍然大明白了吧: 更新插件用的是external storage 中的web项目的version。可以用如下方式重置缓存:

  • 手动卸载app,重装
  • 增加build version,强制插件重装www文件夹。你可以更改config.xml中的 android-versionCodeios-CFBundleVersion来达到该目的。
  • 安装 local development add-on, 这个插件可以帮你完成任务。它会自动增加版本号。不过xcode9下,它会报bug,因为它是用swift编译的,需要你更改一些代码,会有点儿蛋疼。

也许你已经注意到了,在www文件中有一个 chcp.json文件,文件中有一个 release字段,这个是用来定义web内容的version的。它是必须要有的字段,而且在每个release中必须是惟一的。它有CLI生成,格式如:yyyy.MM.dd-HH.mm.ss (i.e., 2015.09.01-13.30.35).

更新插件会为每一个release在external storage 创建一个同名的文件夹,同时把所有的web相关文件放入其中。它是项目的基地址。这种方式可以解决如下几个问题:

  • 文件缓存问题。例如:在iOS中css文件被UIWebView缓存,即使reload了index page,新的样式也不会被显示。这时你必须杀掉APP,或者用一些奇淫技巧来改变css的url
  • 不会出现更新的内容被已存在的内容污染混淆,因为每次release更新用的是完全不同的文件夹
  • 如果被污染了,我们还可以 rollback 到上一个版本

例如,假设当前我们的APP运行着 2015.12.01-12.01.33版本。 意味着:

  • 所有的web内容都存储在/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

过了一阵,我们发布了新的版本: 2016.01.03-10.45.01。首先,更新插件会在设备上加载它,同时:

  • 一个新的文件夹在external storage 中创建: /sdcard/some_path/2016.01.03-10.45.01/.
  • 其中 update文件夹被创建 :/sdcard/some_path/2016.01.03-10.45.01/update/
  • 所有chcp.manifest 中标记的新的或变更的文件都将放置在 update文件夹中
  • 这部分release会被下载到应用内部,并做好安装准备

当安装更新时:

  1. 更新插件拷贝当前版本(正显示给用户的)的www文件夹到新版本 release的文件夹。例如,拷贝所有/sdcard/some_path/2015.12.01-12.01.33/www/下的文件到/sdcard/some_path/2016.01.03-10.45.01/www/
  2. 拷贝update目录下的新文件,更新的文件以及配置文件到www目录中。例如:/sdcard/some_path/2016.01.03-10.45.01/update/ -> /sdcard/some_path/2016.01.03-10.45.01/www/
  3. 移除 /sdcard/some_path/2016.01.03-10.45.01/update/ 目录,我们已经不再需要它了
  4. 从新release中加载index page:/sdcard/some_path/2016.01.03-10.45.01/www/index.html

此时更新插件将会从新release目录中加载index page,以前的release的将会作为备份以防万一。

Step1 Create the Application

通过命令行创建新的ionic空白项目

ionic start chcp-example blank
cd .\chcp-example

Step2 Install Plugins

这里不用官方推荐的内置服务器,此处选择更灵活的 lite-server, 通过它提供的服务器来更新APP。 我们需要

  • lite-server全局安装

  • 并添加iOS和Android平台支持

  • 安装 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

首先,在命令行执行 cordova-hcp init按照提示输入信息,不用担心Amazon相关的信息,可以不用填写

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

此时,你可以看到项目根目录新生成了一个文件 cordova-hcp.json,内容大概如下:

{
    "name": "chcp-example",
    "ios_identifier": "",
    "android_identifier": "",
    "update": "start",
    "content_url": "http://youserverip:3000/updates"
}

编辑 config.xml文件,因为要悄悄的自动下载和安装,所以要打开自动下载和自动安装配置。

<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在手机或模拟器上继续running, 现在改动home.html 文件中的文字

更改完毕后再次执行如下命令:

cordova prepare ios 
cordova-hcp build

更新后的代码会在 www文件夹下生成信息的文件

Step7 Providing the Updated Code

在与项目文件夹chcp-example平级处创建 lite-server的目录chcp-example-server,并创建子其目录updates— 这是用来放将要发布的代码更新。

用命令行来启动lite-server

chcp-example-server>lite-server

因为是在本机测试,需要将你的手机与电脑连接到同一个局域网中,然后手机的网络代理设置成电脑的ip+端口号3000. iOS的具体设置

www文件夹中的所有内容拷贝到 updates文件夹中。

回到手机上的APP,然后手动杀掉它。然后重新打开,3秒内白屏一闪, 改动就可以看到了。

更多阅读:

文档地址

Implementing Cordova Hot Code Push in Your Ionic App

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,326评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,228评论 1 304
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,979评论 0 252
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,489评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,894评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,900评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,075评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,803评论 0 205
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,565评论 1 249
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,778评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,255评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,582评论 3 261
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,254评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,151评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,952评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,035评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,839评论 2 277