深入:ionic中使用热更新插件cordova-hot-code-push

之前两篇文章中,《续:ionic中使用热更新插件cordova-hot-code-push》以及《ionic中使用热更新插件cordova-hot-code-push》我都分别叙述了app内容更新以及外壳更新的相关配置与实现,今天我们则深入使用内外更新的功能,并且完成一个启动app后,如果检测有更新,则执行loading,并显示“正在下载更新”、“正在更新中”等字样,如果没有检测到更新,则不显示loading。

1、准备工作

由于ionic中的LoadingController仅能显示一次数据,LoadingController中无法使用变量进行随时更新显示,因此我们得自己编写一个loading样式。我们需要的功能是当用户打开app后就提示有更新,如果是内容更新,那么则自动下载,并提示一个loading,loading中显示“正在下载更新文件”,“下载完成后,准备更新”等等,就有点像12306打开app时的升级提醒吧!

2、相关代码

为了你能快速的入手,请先查看之前的两篇文章后再来进行相应的操作。否则可能会尝试无效!废话不多说,下面直接看代码:

import { Component } from '@angular/core';
import { NavController,LoadingController,AlertController,Platform } from 'ionic-angular';
import { Http } from '@angular/http';


declare var window;

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage  {
  public updateText='正在下载更新包';
  public showUpdate:boolean=false;
  public interval:any;
  public url:any;
  constructor(
    public navCtrl: NavController,
    public loadingCtrl:LoadingController,
    public alertCtrl:AlertController,
    public http:Http,
    public platform: Platform) {
    //console.log('chcp check', window.chcp);
       if(this.platform.is("android")){
         console.log('android');
         this.url = 'http://192.168.22.62/tabs/chcp.json'
       }
       if(this.platform.is("ios")){
         this.url = 'https://dockyard-ios.gobindo.com/chcp.json';
         console.log('ios')
       }
     
      this.initialize();
   
   console.log(this.url)
    this.interval = setInterval(() => {
      this.showUpdate;
      this.updateText;
      console.log('正在跑')
    }, 10)

  }

  onShowUpdate(){
    this.showUpdate=true;
  }
  hiddenUpdate(){
    this.showUpdate=false;
  }
  //内壳外壳,更新
  initialize() {
    this.bindEvents();
  }
  bindEvents() {
    document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
    //当插件无法从服务器加载更新时发送。错误详细信息附加到事件。用于外壳更新
    document.addEventListener('chcp_updateLoadFailed', this.onUpdateLoadError.bind(this), false);
    //当新版本成功加载并准备安装时发送
    document.addEventListener('chcp_updateIsReadyToInstall', this.onReadyToInstall.bind(this), false);
    //在即将安装更新时发送。
    document.addEventListener('chcp_beforeInstall', this.onBeforeInstall.bind(this), false);
    //成功安装更新
    document.addEventListener('chcp_updateInstalled', this.onInstalle.bind(this), false);
    //安装更新失败时
    document.addEventListener('chcp_updateInstallFailed', this.installError.bind(this), false);
    //当用户手机存储卡不够用时
    document.addEventListener('chcp_assetsInstallationError', this.onInstallationError.bind(this), false);
  }

  // deviceready Event Handler
  onDeviceReady() {
    window.chcp.getVersionInfo((error,data)=>{
      if(error){
        console.log(error)
      }
      console.log(data.currentWebVersion);
      let currentWebVersion = data.currentWebVersion;
      let release;
      this.http.get(this.url).subscribe((data)=>{
        release = data.json();
        console.log(release.release);
        if(release.release!=currentWebVersion){
        this.interval;
        this.onShowUpdate();
        window.chcp.fetchUpdate(this.fetchUpdateCallback.bind(this));
        }
      });
    });
   
  }
  installError(){
    console.log('安装更新失败')
  }
  installationCallback(error) {
    if (error) {
      //console.log('Failed to install the update with error code: ' + error.code);
      //console.log(error.description);
          let alert = this.alertCtrl.create({
          title: '更新不成功',
          message: '安装更新包过程中发生错误,请重启app再次尝试升级',
          buttons: [
            {
              text: '明白了',
              role: 'cancel',
              handler: () => {}
            }
          ]
        });
        alert.present();
     
    } else {
      console.log('Update installed!');
    }
  }

  fetchUpdateCallback(error, data ) {
      console.log('发生错误,错误代码: ' + error.code);
      if(error.code===-3 || error.code===-4){
            this.hiddenUpdate();
            window.clearInterval()
            var dialogMessage = '下载失败,去App store下载最新版';
            window.chcp.requestApplicationUpdate(dialogMessage);
      }
      // console.log(error.description);
      //error.code=2没有更新,error.code=-17下载正在进行
      if(error){
          //loading.dismiss();
          //console.log('没有检测到任何文件更新')
          //console.log(error.description);
         
          this.hiddenUpdate();
          setTimeout(()=>{
            window.clearInterval(this.interval)
          },100)
         
      }
        console.log('文件加载中');
     
     
  }
  //外壳更新
  onUpdateLoadError(eventData) {
    var error = eventData.detail.error;
    if (error && error.code == window.chcp.error.APPLICATION_BUILD_VERSION_TOO_LOW) {
        //console.log('Native side update required');
        var dialogMessage = '发现新版本,即刻下载安装.';
        window.chcp.requestApplicationUpdate(dialogMessage);
    }
  }
  userWentToStoreCallback() {}
  userDeclinedRedirectCallback() {}
  //当新版本成功加载并准备安装时发送
  onReadyToInstall(){
    //console.log('正在安装更新');
    this.updateText = '正在安装更新'
    window.chcp.installUpdate(this.installationCallback.bind(this));
  }
  //安装即将开始
  onBeforeInstall(){
    this.updateText = '即将开始升级'
  }
  //安装更新成功
  onInstalle(){
    //console.log('升级完成')
    this.updateText = '升级完成'
    this.hiddenUpdate();
    setTimeout(()=>{
      window.clearInterval(this.interval)
    },100)
  }
  //存储卡不够用时提醒用户
  onInstallationError(){
    //console.log('存储空间不够升级')
    let alert = this.alertCtrl.create({
      title: '存储错误',
      message: '您的手机存储不足,无法下载更新包',
      buttons: [
        {
          text: '明白了',
          role: 'cancel',
          handler: () => {}
        }
      ]
    });
    alert.present();
  }

}

3、html代码

在ion-content中加入如下代码:

<div class="bg" *ngIf="showUpdate"></div>
  <div class="progress-bar" *ngIf="showUpdate">
    <ion-spinner></ion-spinner>
    <p>{{updateText}}</p>
  </div>

4、scss文件代码

page-home {
     .bg{
        background: rgba(0, 0, 0, .7);
        position: absolute;
        top:0;
        left:0;
        width: 100%;
        height: 100%;
    }
    .progress-bar{
        position: absolute;
        top:50%;
        left: 50%;
        z-index: 10;
        margin: 0 auto;
        padding: 10px 30px;
        border-radius: 4px;
        min-width: 20%;
        max-width:80%;
        background: #fff;
        text-align: center;
        -webkit-transform: translate(-50%,-50%);
        -moz-transform: translate(-50%,-50%);
        transform:translate(-50%,-50%);
    }
    p{
        padding: 5px 0 0 0;
    }
    ion-spinner * {
        width: 40px;
        height: 40px;
        stroke: #444;
        fill: #222;
        margin: 0 auto;
    }
}

5、最重要的一步

为了不让app启动后就开始自动下载更新文件,这样会导致我们上面的loading效果无效。因此我们得禁止app启动后就自动更新,这个必须在config.xml里面进行设置。
增加如下代码

<auto-download enabled="false" />
<auto-install enabled="false" />

最终的config.xml中显示的内容:

<widget>
  ..............
  <chcp>
    <native-interface version="5"/>
    <config-file url="http://192.168.22.62/tabs/chcp.json"/>
    <auto-download enabled="false" />
    <auto-install enabled="false" />
  </chcp>
</widget>

发表评论

电子邮件地址不会被公开。 必填项已用*标注