uniapp實(shí)現(xiàn)app檢查更新與升級(jí)詳解(uni-upgrade-center)
app檢查更新與升級(jí)
參考鏈接:
什么是升級(jí)中心uni-upgrade-center
uniapp官方開發(fā)的App版本更新的插件,基于unicloud的后端服務(wù)
因?yàn)槭情_源的,通過修改源碼可以實(shí)現(xiàn)請(qǐng)求java等其他后端服務(wù),后續(xù)的源碼解析章節(jié)會(huì)介紹
升級(jí)中心分為兩個(gè)部分:
前臺(tái)檢測更新: uni-upgrade-center-app
后臺(tái)管理系統(tǒng):
uni-admin >= 1.9.3:uni-admin 已內(nèi)置 升級(jí)中心,直接使用即可。并且云函數(shù)upgrade-center廢棄,使用uni-upgrade-center云函數(shù)。- uni-upgrade-center Admin管理后臺(tái) (uni-admin 1.9.3+ 已內(nèi)置,此插件不再維護(hù))
簡單來說,如果是新版的uni-admin,直接用升級(jí)中心即可
怎么使用uni-upgrade-center
使用我覺得并不難,跟著官方文檔走即可
簡單來說,就是你的app項(xiàng)目安裝 uni-upgrade-center-app這個(gè)插件,同時(shí)你需要另外新建一個(gè)uni-admin項(xiàng)目,用來上傳并管理app項(xiàng)目的更新包,app項(xiàng)目通過unicloud請(qǐng)求更新包
但是如果不想使用unicloud,想換成java等其他后端服務(wù),或者想了解app檢查更新與升級(jí)的代碼是如何編寫的,閱讀uni-upgrade-center源碼是十分有必要的。
uni-upgrade-center源碼閱讀
十分推薦閱讀uni-upgrade-center源碼
通過一步步閱讀uni-upgrade-center源碼,基本能完全學(xué)會(huì)如何寫app檢查更新與升級(jí)的代碼
源碼前端功能實(shí)現(xiàn)主要分為三個(gè)文件,依次閱讀
utils/call-check-version.jsutils/call-check-version.jspages/upgrade-popup.vue
utils/call-check-version.js
代碼很簡單,通過h5+ api獲取應(yīng)用信息,把應(yīng)用信息傳遞給uniCloud云函數(shù)
同理,如果不使用云函數(shù),傳給java等后端服務(wù)的話,替換云函數(shù)部分代碼就可以了
export default function () {
// #ifdef APP-PLUS
return new Promise((resolve, reject) => {
// 根據(jù)當(dāng)前應(yīng)用的appid,獲取appid對(duì)應(yīng)的應(yīng)用信息
plus.runtime.getProperty(plus.runtime.appid, function (widgetInfo) {
const data = {
action: 'checkVersion',
appid: plus.runtime.appid,
appVersion: plus.runtime.version,
wgtVersion: widgetInfo.version
}
console.log("data: ", data);
// 如果傳給java等后端服務(wù),改下方代碼
uniCloud.callFunction({
name: 'uni-upgrade-center',
data,
success: (e) => {
console.log("e: ", e);
resolve(e)
},
fail: (error) => {
reject(error)
}
})
})
})
// #endif
// #ifndef APP-PLUS
return new Promise((resolve, reject) => {
reject({
message: '請(qǐng)?jiān)贏pp中使用'
})
})
// #endif
}
plus.runtime.appid
當(dāng)前應(yīng)用的APPID
String 類型 只讀屬性
注意,如果是在HBuilder真機(jī)運(yùn)行獲取的是固定值"HBuilder",需要提交App云端打包后運(yùn)行才能獲取真實(shí)的APPID值
plus.runtime.getProperty
獲取指定APPID對(duì)應(yīng)的應(yīng)用信息
參數(shù):
- appid: ( String ) 必選 應(yīng)用的Appid
- getPropertyCB: ( GetPropertyCallBack ) 必選 獲得應(yīng)用信息成功回調(diào)函數(shù)
示例:
// 獲取應(yīng)用信息
function getAppInfo() {
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 );
} );
}
utils/call-check-version.js
官方實(shí)現(xiàn)了兩種方式,靜默更新和提示更新
import callCheckVersion from './call-check-version'
// 推薦在App.vue中使用
const PACKAGE_INFO_KEY = '__package_info__'
export default function() {
// #ifdef APP-PLUS
return new Promise((resolve, reject) => {
callCheckVersion().then(async (e) => {
if (!e.result) return;
const {
code,
message,
is_silently, // 是否靜默更新
url, // 安裝包下載地址
platform, // 安裝包平臺(tái)
type // 安裝包類型
} = e.result;
// 此處邏輯僅為實(shí)例,可自行編寫
if (code > 0) {
// 騰訊云和阿里云下載鏈接不同,需要處理一下,阿里云會(huì)原樣返回
const {
fileList
} = await uniCloud.getTempFileURL({
fileList: [url]
});
if (fileList[0].tempFileURL)
e.result.url = fileList[0].tempFileURL;
resolve(e)
// 靜默更新,只有wgt有
if (is_silently) {
uni.downloadFile({
url: e.result.url,
success: res => {
if (res.statusCode == 200) {
// 下載好直接安裝,下次啟動(dòng)生效
plus.runtime.install(res.tempFilePath, {
force: false
});
}
}
});
return;
}
/**
* 提示升級(jí)一
* 使用 uni.showModal
*/
// return updateUseModal(e.result)
/**
* 提示升級(jí)二
* 官方適配的升級(jí)彈窗,可自行替換資源適配UI風(fēng)格
*/
uni.setStorageSync(PACKAGE_INFO_KEY, e.result)
uni.navigateTo({
url: `/uni_modules/uni-upgrade-center-app/pages/upgrade-popup?local_storage_key=${PACKAGE_INFO_KEY}`,
fail: (err) => {
console.error('更新彈框跳轉(zhuǎn)失敗', err)
uni.removeStorageSync(PACKAGE_INFO_KEY)
}
})
return
} else if (code < 0) {
// TODO 云函數(shù)報(bào)錯(cuò)處理
console.error(message)
return reject(e)
}
return resolve(e)
}).catch(err => {
// TODO 云函數(shù)報(bào)錯(cuò)處理
console.error(err.message)
reject(err)
})
});
// #endif
}
/**
* 使用 uni.showModal 升級(jí)
*/
function updateUseModal(packageInfo) {
const {
title, // 標(biāo)題
contents, // 升級(jí)內(nèi)容
is_mandatory, // 是否強(qiáng)制更新
url, // 安裝包下載地址
platform, // 安裝包平臺(tái)
type // 安裝包類型
} = packageInfo;
let isWGT = type === 'wgt'
let isiOS = !isWGT ? platform.includes('iOS') : false;
let confirmText = isiOS ? '立即跳轉(zhuǎn)更新' : '立即下載更新'
return uni.showModal({
title,
content: contents,
showCancel: !is_mandatory,
confirmText,
success: res => {
if (res.cancel) return;
// 安裝包下載
if (isiOS) {
plus.runtime.openURL(url);
return;
}
uni.showToast({
title: '后臺(tái)下載中……',
duration: 1000
});
// wgt 和 安卓下載更新
downloadTask = uni.downloadFile({
url,
success: res => {
if (res.statusCode !== 200) {
console.error('下載安裝包失敗', err);
return;
}
// 下載好直接安裝,下次啟動(dòng)生效
plus.runtime.install(res.tempFilePath, {
force: false
}, () => {
if (is_mandatory) {
//更新完重啟app
plus.runtime.restart();
return;
}
uni.showModal({
title: '安裝成功是否重啟?',
success: res => {
if (res.confirm) {
//更新完重啟app
plus.runtime.restart();
}
}
});
}, err => {
uni.showModal({
title: '更新失敗',
content: err
.message,
showCancel: false
});
});
}
});
}
});
}
靜默更新
可以看出靜默更新分為三步:
- 后端提供一個(gè)下載更新包的url
- 前端
uni.downloadFile該url地址 - 下載好后前端調(diào)用
plus.runtime.install安裝更新包
// 靜默更新,只有wgt有
if (is_silently) {
uni.downloadFile({
url: e.result.url,
success: res => {
if (res.statusCode == 200) {
// 下載好直接安裝,下次啟動(dòng)生效
plus.runtime.install(res.tempFilePath, {
force: false
});
}
}
});
return;
}
強(qiáng)制更新
首先,我們需要知道的是,plus.runtime.install成功后就已經(jīng)安裝完更新包了,用戶下次打開app就會(huì)是最新版的app,這里強(qiáng)制更新的意思是是否立刻重啟app,強(qiáng)制用戶立刻使用最新版app
plus.runtime.install后有三種應(yīng)用場景,這里官方寫的很好,三種場景都處理了:
- 不征求客戶意見,直接重啟app,強(qiáng)制用戶立刻使用最新版
- 征求客戶意見,如果重啟,用戶使用最新版,如果不重啟,等用戶下次打開app顯示最新版
- 不重啟,等用戶下次打開app顯示最新版
// 安裝下載的安裝包,下次啟動(dòng)生效
plus.runtime.install(res.tempFilePath, {
force: false
}, () => {
// is_mandatory是后端返回的控制是否強(qiáng)制更新的變量
// 強(qiáng)制更新就是強(qiáng)制重啟app,否則就是用戶下次打開app才會(huì)更新
// 強(qiáng)制更新體驗(yàn)不好,還是下次打開更新會(huì)好很多
if (is_mandatory) {
// 更新完重啟app
plus.runtime.restart();
return;
}
uni.showModal({
title: '安裝成功是否重啟?',
success: res => {
if (res.confirm) {
// 更新完重啟app
plus.runtime.restart();
}
}
});
}, err => {
uni.showModal({
title: '更新失敗',
content: err
.message,
showCancel: false
});
});
跳轉(zhuǎn)應(yīng)用商店
- 后端返回安裝包平臺(tái)和安裝包類型
- 安裝包類型是否是
wgt,如果不是,判斷安裝包平臺(tái)是否包含iOS,調(diào)用第三方程序打開url安裝iOS更新包,iOS是跳轉(zhuǎn)更新,其他是下載更新 - ios需要上架、通過市場安裝,所以需要第三方程序打開url
plus.runtime.openURL表示調(diào)用第三方程序打開url進(jìn)行安裝,即跳轉(zhuǎn)應(yīng)用商店功能
function updateUseModal(packageInfo) {
const {
title, // 標(biāo)題
contents, // 升級(jí)內(nèi)容
is_mandatory, // 是否強(qiáng)制更新
url, // 安裝包下載地址
platform, // 安裝包平臺(tái)
type // 安裝包類型
} = packageInfo;
let isWGT = type === 'wgt'
let isiOS = !isWGT ? platform.includes('iOS') : false;
let confirmText = isiOS ? '立即跳轉(zhuǎn)更新' : '立即下載更新'
return uni.showModal({
title,
content: contents,
showCancel: !is_mandatory,
confirmText,
success: res => {
if (res.cancel) return;
// 安裝包下載
if (isiOS) {
plus.runtime.openURL(url);
return;
}
...
}
});
}
用戶取消下載
https://uniapp.dcloud.net.cn/api/request/network-file.html#downloadfile
var downloadTask = uni.downloadFile({
url: 'https://www.example.com/file/test', //僅為示例,并非真實(shí)接口地址。
complete: ()=> {}
});
downloadTask.abort();如何打包wgt資源包
一、更改項(xiàng)目manifest.json中的應(yīng)用版本名稱與應(yīng)用版本號(hào)

二、HBuilderX>發(fā)行>原生App-制作應(yīng)用wgt包>確定


三、開發(fā)測試的時(shí)候,記得再改回原先的應(yīng)用版本名稱與應(yīng)用版本號(hào),不然版本跟線上的相同,安裝更新包的時(shí)候就會(huì)出現(xiàn)WGT安裝包中manifest.json文件的version版本不匹配,本地測試不了更新效果
如何查看wgt文件manifest.json
wgt包生成后會(huì)是.wgt后綴名,更改其后綴名為.zip,再解壓,就可以查看manifest.json了
報(bào)錯(cuò)解決:WGT安裝包中manifest.json文件的version版本不匹配
manifest.json中的版本大于等于了線上的版本,自行排查即可
通過uni-admin上傳wgt資源包

uni-admin報(bào)錯(cuò)解決:超級(jí)管理員已存在
是因?yàn)閍dmin賬戶是舊的,跟appid對(duì)不上,刪除舊的admin賬戶,重新創(chuàng)建
總結(jié)
到此這篇關(guān)于uniapp實(shí)現(xiàn)app檢查更新與升級(jí)(uni-upgrade-center)的文章就介紹到這了,更多相關(guān)uniapp app檢查更新與升級(jí)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
uniApp獲取當(dāng)前位置經(jīng)緯度的示例代碼
這篇文章主要介紹了uniApp獲取當(dāng)前位置經(jīng)緯度,以下是使用uni.getLocation獲取當(dāng)前位置的示例代碼,需要的朋友可以參考下2024-01-01
JavaScript實(shí)現(xiàn)自動(dòng)切換圖片代碼
本文給大家分享一段js代碼實(shí)現(xiàn)自動(dòng)切換圖片的代碼,代碼非常簡單,應(yīng)用領(lǐng)域非常廣泛,感興趣的朋友一起看看吧2016-10-10
javascript實(shí)現(xiàn)checkbox全選的代碼
本文給大家分享的是js實(shí)現(xiàn)checkbox的全選的代碼,在網(wǎng)頁制作中很常用的js代碼,供大家學(xué)習(xí)參考。2015-04-04
ionic 上拉菜單(ActionSheet)實(shí)例代碼
ionic js 上拉菜單(ActionSheet)通過往上彈出的框,來讓用戶選擇選項(xiàng);點(diǎn)擊取消按鈕或者點(diǎn)擊空白的地方來讓它消失。本文給大家分享實(shí)現(xiàn)代碼,感興趣的朋友一起看看吧2016-06-06
JavaScript中click和onclick本質(zhì)區(qū)別與用法分析
這篇文章主要介紹了JavaScript中click和onclick本質(zhì)區(qū)別與用法,結(jié)合實(shí)例形式分析了JavaScript中click和onclick的具體概念、功能、使用場景及相關(guān)操作技巧,需要的朋友可以參考下2018-06-06

