享阅客栈

Ionic 热更新实践笔记
Ionic 热更新实践笔记参考了官方文档 ,和Sean Chase 大神的Implementing Cordova...
扫描右侧二维码阅读全文
21
2019/11

Ionic 热更新实践笔记

Ionic 热更新实践笔记

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

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

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

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

[TOC]

注意事项

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

Update workflow

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

流程图如下:

https://github.com/nordnet/cordova-hot-code-push/raw/master/docs/images/update-workflow.png?raw=true

  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

Last modification:November 21st, 2019 at 09:02 pm
If you think my article is useful to you, please feel free to appreciate

One comment

  1. 享阅客栈

    斯国一

Leave a Comment