美文网首页Ionic开发笔记
Ionic 热更新实践笔记

Ionic 热更新实践笔记

作者: 一只特立独行的道哥 | 来源:发表于2018-09-04 14:07 被阅读354次

    参考了官方文档 ,和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

    相关文章

      网友评论

        本文标题:Ionic 热更新实践笔记

        本文链接:https://www.haomeiwen.com/subject/bopgwftx.html