uni-app: 如何實現增量更新功能?

  • 2019 年 10 月 6 日
  • 筆記

都知道,很多APP都有增量更新功能,Uni APP也是在今年初,推出了增量更新功能,今天我們就來學習一波。 當然,很多應用市場為了防止開發者不經市場審核許可,給用戶提供違法內容,對增量更新大多持排斥態度,特別是apple。所以擁有增量更新的app,需要注意以下幾點:

1、上架審核期間不要彈出增量更新提示

2、增量更新內容使用https下載,避免被三方網路劫持

3、不要更新違法內容、不要通過增量更新破壞應用市場的利益,比如iOS的虛擬支付要給Apple抽佣等

通過本章節你能學到那些?

1、如何實現增量更新功能 2、Uni-App 如何製作增量更新升級包 3、Uni-App 增量更新功能需要注意些什麼 4、Uni-App 部分相關api學習

話不多說,直接上乾貨!

如何實現增量更新功能

這裡不是針對Uni-App開發,所有的增量更新都應如此(但程式碼以Uni-App為例)。

1、app端,先調用服務端介面,判斷是否需要更新

2、需要更新,直接下載更新升級包

3、安裝升級包,app重啟即可完成升級

ok,我們以Uni-App為例,看看程式碼具體實現

客戶端實現 在 根目錄 App.vue 的 onLaunch 中檢測升級,程式碼如下:

// #ifdef APP-PLUS  plus.runtime.getProperty(plus.runtime.appid, function(widgetInfo) {      uni.request({          url: 'http://www.javanx.cn/update/',          data: {              version: widgetInfo.version,              name: widgetInfo.name          },          success: (result) => {              var data = result.data;              if (data.update && data.wgtUrl) {                  uni.downloadFile({                      url: data.wgtUrl,                      success: (downloadResult) => {                          if (downloadResult.statusCode === 200) {                              plus.runtime.install(downloadResult.tempFilePath, {                                  force: false                              }, function() {                                  console.log('install success...');                                  plus.runtime.restart();                              }, function(e) {                                // 這裡的錯誤很重要,最好能記錄的伺服器日誌中,方便調試或以後維護了解更新錯誤情況,及時解決                                // 如何更新到伺服器?                                // 調用一個介面,將e返回咯                                console.error('install fail...');                              });                          }                      }                  });              }          }      });  });  // #endif

程式碼解析: 1、#ifdef APP-PLUS 判斷是app端,才檢測是否需要更新

2、plus.runtime.getProperty 獲取指定APPID對應的應用資訊

plus.runtime.getProperty( plus.runtime.appid, function ( wgtinfo ) {    //appid屬性    var wgtStr = "appid:"+wgtinfo.appid;    //version屬性    wgtStr += "<br/>version:"+wgtinfo.version;    //name屬性    wgtStr += "<br/>name:"+wgtinfo.name;    //description屬性    wgtStr += "<br/>description:"+wgtinfo.description;    //author屬性    wgtStr += "<br/>author:"+wgtinfo.author;    //email屬性    wgtStr += "<br/>email:"+wgtinfo.email;    //features 屬性    wgtStr += "<br/>features:"+wgtinfo.features;    console.log( wgtStr );  } );

3、uni.request調用服務端介面,傳入當前版本,服務端返回update是否需要更新,需要更新時返回wgtUrl更新升級包路徑。

4、uni.downloadFile 下載文件資源到本地,客戶端直接發起一個 HTTP GET 請求,返迴文件的本地臨時路徑tempFilePath。如何我們需要監聽下載進度,可以這樣:

var downloadTask = uni.downloadFile({      url: 'https://www.javanx.cn/file/uni-app.rar',      complete: ()=> {}  });  downloadTask.onProgressUpdate(function(res)=>{    console.log('下載進度' + res.progress);    console.log('已經下載的數據長度' + res.totalBytesWritten);    console.log('預期需要下載的數據總長度' + res.totalBytesExpectedToWrite);  })

downloadTask 對象的還提供了一下方法: (1)、abort 中斷下載任務

(2)、onHeadersReceived` 監聽 HTTP Response Header 事件,會比請求完成事件更早,僅微信小程式平台支援

(3)、offProgressUpdate 取消監聽下載進度變化事件,僅微信小程式平台支援

(4)、offHeadersReceived 取消監聽 HTTP Response Header 事件,僅微信小程式平台支援

5、plus.runtime.install(filePath, options, installSuccessCB, installErrorCB)。 支援以下類型安裝包:

(1)、應用資源安裝包(wgt),擴展名為'.wgt';

(2)、應用資源差量升級包(wgtu),擴展名為'.wgtu';

(3)、系統程式安裝包(apk),要求使用當前平台支援的安裝包格式。 注意:僅支援本地地址,調用此方法前需把安裝包從網路地址或其他位置放置到運行時環境可以訪問的本地目錄。

服務端實現 以nodejs為例:

var express = require('express');  var router = express.Router();  var db = require('./db');    // TODO 查詢配置文件或者資料庫資訊來確認是否有更新  function checkUpdate(params, callback) {      db.query('一段SQL', function(error, result) {          // 這裡簡單判定下,不相等就是有更新。          var currentVersions = params.appVersion.split('.');          var resultVersions = result.appVersion.split('.');            if (currentVersions[0] < resultVersions[0]) {              // 說明有大版本更新              callback({                  update: true,                  wgtUrl: '',                  pkgUrl: result.pkgUrl // apk,ipa包可下載地址              })          } else if (currentVersions[currentVersions.length-1] < resultVersions[resultVersions.length-1]) {            // 認為是小版本更新              callback({                  update: true,                  wgtUrl: result.wgtUrl, // wgt包可下載地址                  pkgUrl: ''              })          }  else {              // 其它情況均不更新              callback({                  update: false              })          }      });  }    router.get('/update/', function(req, res) {      var appName = req.query.name;      var appVersion = req.query.version;      checkUpdate({          appName: appName,          appVersion: appVersion      }, function(error, result) {          if (error) {              throw error;          }          res.json(result);      });  });

ok,有了以上的功能,我們就用HBuilderx製作升級包.wgt,放到伺服器上,共升級使用。

Uni-App 如何製作增量更新升級包

1、更新 manifest.json 中的版本號。如果上一個版本的版本號是1.0.0,這裡打升級包的時候就可以是1.0.1,反正要不前面的大,大家也可看到服務端介面實現了,就是通過版本號來判斷的。

2、菜單->發行->原生App-製作移動App資源升級包

3、等待控制台生成升級包的輸出位置

4、將升級包上傳到伺服器,介面實現並返回:wgtUrl=剛剛打的升級包

這樣,我們的app就擁有了,增量更新功能。每次如果是小量更新,就可以通過wgt包,來實現增量更新。

下面來看看,Uni App增量更新時,需要注意哪些問題?

Uni-App 增量更新功能需要注意些什麼

1、SDK 部分有調整,比如新增了 Maps 模組等,不可通過此方式升級,必須通過整包的方式升級。

2、如果是老的非自定義組件編譯模式,之前沒有 nvue 文件,但更新中新增了 nvue 文件,不能使用此方式。因為非自定義組件編譯模式如果沒有 nvue 文件是不會打包weex引擎進去的,原生引擎無法動態添加。自定義組件模式默認就含著weex引擎,不管工程下有沒有nvue文件。

3、原生插件的增改,同樣不能使用此方式。

4、#ifdef APP-PLUS 條件編譯,僅在 App 平台執行此升級邏輯。

5、appid 以及版本資訊等,在 HBuilderX 真機運行開發期間,均為 HBuilder 這個應用的資訊,因此需要打包自定義基座或正式包測試升級功能。

6、plus.runtime.version 或者uni.getSystemInfo() 讀取到的是 apk/ipa 包的版本號,而非 manifest.json 資源中的版本資訊,所以這裡用 plus.runtime.getProperty() 來獲取相關資訊。

7、安裝 wgt 資源包成功後,必須執行 plus.runtime.restart(),否則新的內容並不會生效。

8、如果App的原生引擎不升級,只升級wgt包時需要注意測試wgt資源和原生基座的兼容性。平台默認會對不匹配的版本進行提醒,如果自測沒問題,可以在manifest中配置忽略提示

總結

今天你學到了什麼?Uni-App 增量更新你學會了嗎?