app check for updates and upgrades
Reference link:
Upgrade Center uni-upgrade-center - App
Online upgrade and update of App resources
What is the upgrade center uni-upgrade-center
App version update plug-in officially developed by uniapp, based on unicloud backend service
Because it is open source, you can request java and other back-end services by modifying the source code, which will be introduced in the subsequent chapters on source code analysis
The Upgrade Center is divided into two parts:
Foreground detection update: uni-upgrade-center-app
Background management system:
uni-admin >= 1.9.3
: uni-admin has a built-in upgrade center, which can be used directly. And the cloud functionupgrade-center
is deprecated , useuni-upgrade-center
the cloud function.- uni-upgrade-center Admin management background (uni-admin 1.9.3+ has been built in, this plugin is no longer maintained)
To put it simply, if it is a new version of uni-admin, just use the upgrade center directly
How to use uni-upgrade-center
I don't think it is difficult to use, just follow the official documentation
Simply put, your app project installs the uni-upgrade-center-app plug-in, and you need to create another uni-admin
project to upload and manage the update package of the app project. The app project requests the update package through unicloud
But if you don't want to use unicloud, want to switch to other back-end services such as java, or want to understand how the code for app checking for updates and upgrades is written, it is very uni-upgrade-center
necessary to read the source code.
uni-upgrade-center
Source code reading
It is highly recommended to read uni-upgrade-center
the source code
By reading the source code step by step uni-upgrade-center
, you can basically learn how to write the code for app checking for updates and upgrades
The front-end function implementation of the source code is mainly divided into three files, read in turn
utils/call-check-version.js
utils/call-check-version.js
pages/upgrade-popup.vue
utils/call-check-version.js
The code is very simple, get the application information through the h5+ api, and pass the application information to the uniCloud cloud function
Similarly, if you do not use cloud functions and pass them to back-end services such as java, you can replace part of the code of the cloud functions.
export default function () {
// #ifdef APP-PLUS
return new Promise((resolve, reject) => {
// 根据当前应用的appid,获取appid对应的应用信息
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等后端服务,改下方代码
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: '请在App中使用'
})
})
// #endif
}
plus.runtime.appid
APPID of the current application
String type read-only property
Note that if the fixed value "HBuilder" is obtained by running HBuilder on a real machine, you need to submit the App to the cloud for packaging and then run it to obtain the real APPID value
plus.runtime.getProperty
Get the application information corresponding to the specified APPID
parameter:
- appid: ( String ) Appid of the required application
- getPropertyCB: ( GetPropertyCallBack ) Required callback function for obtaining application information successfully
Example:
// 获取应用信息
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
The official implements two methods, silent update and prompt update
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, // 安装包平台
type // 安装包类型
} = e.result;
// 此处逻辑仅为实例,可自行编写
if (code > 0) {
// 腾讯云和阿里云下载链接不同,需要处理一下,阿里云会原样返回
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) {
// 下载好直接安装,下次启动生效
plus.runtime.install(res.tempFilePath, {
force: false
});
}
}
});
return;
}
/**
* 提示升级一
* 使用 uni.showModal
*/
// return updateUseModal(e.result)
/**
* 提示升级二
* 官方适配的升级弹窗,可自行替换资源适配UI风格
*/
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('更新弹框跳转失败', err)
uni.removeStorageSync(PACKAGE_INFO_KEY)
}
})
return
} else if (code < 0) {
// TODO 云函数报错处理
console.error(message)
return reject(e)
}
return resolve(e)
}).catch(err => {
// TODO 云函数报错处理
console.error(err.message)
reject(err)
})
});
// #endif
}
/**
* 使用 uni.showModal 升级
*/
function updateUseModal(packageInfo) {
const {
title, // 标题
contents, // 升级内容
is_mandatory, // 是否强制更新
url, // 安装包下载地址
platform, // 安装包平台
type // 安装包类型
} = packageInfo;
let isWGT = type === 'wgt'
let isiOS = !isWGT ? platform.includes('iOS') : false;
let confirmText = isiOS ? '立即跳转更新' : '立即下载更新'
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: '后台下载中……',
duration: 1000
});
// wgt 和 安卓下载更新
downloadTask = uni.downloadFile({
url,
success: res => {
if (res.statusCode !== 200) {
console.error('下载安装包失败', err);
return;
}
// 下载好直接安装,下次启动生效
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
});
});
}
});
}
});
}
silent update
It can be seen that the silent update is divided into three steps:
- The backend provides a url to download the update package
uni.downloadFile
The url address of the front end- After downloading, the front end calls
plus.runtime.install
the installation update package
// 静默更新,只有wgt有
if (is_silently) {
uni.downloadFile({
url: e.result.url,
success: res => {
if (res.statusCode == 200) {
// 下载好直接安装,下次启动生效
plus.runtime.install(res.tempFilePath, {
force: false
});
}
}
});
return;
}
force update
First of all, what we need to know is that plus.runtime.install
after the success, the update package has been installed. The next time the user opens the app, it will be the latest version of the app. The forced update here means whether to restart the app immediately and force the user to use the latest version of the app immediately.
plus.runtime.install
There are three application scenarios in the end. The official writing here is very good, and all three scenarios are handled:
- Restart the app without asking for customer opinions, forcing users to use the latest version immediately
- Solicit customer opinions, if restart, the user will use the latest version, if not restart, wait for the user to open the app next time to display the latest version
- Do not restart, wait for the user to open the app next time to display the latest version
// 安装下载的安装包,下次启动生效
plus.runtime.install(res.tempFilePath, {
force: false
}, () => {
// is_mandatory是后端返回的控制是否强制更新的变量
// 强制更新就是强制重启app,否则就是用户下次打开app才会更新
// 强制更新体验不好,还是下次打开更新会好很多
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
});
});
Jump to the app store
- The backend returns the installation package platform and installation package type
- Whether the installation package type is
wgt
, if not, determine whether the installation package platform contains itiOS
, call a third-party program to open the url to installiOS
the update package,iOS
it is a jump update, and the other is a download update - iOS needs to be put on the shelves and installed through the market, so a third-party program is required to open the url
plus.runtime.openURL
Indicates calling a third-party program to open the url for installation, that is, jumping to the app store function
function updateUseModal(packageInfo) {
const {
title, // 标题
contents, // 升级内容
is_mandatory, // 是否强制更新
url, // 安装包下载地址
platform, // 安装包平台
type // 安装包类型
} = packageInfo;
let isWGT = type === 'wgt'
let isiOS = !isWGT ? platform.includes('iOS') : false;
let confirmText = isiOS ? '立即跳转更新' : '立即下载更新'
return uni.showModal({
title,
content: contents,
showCancel: !is_mandatory,
confirmText,
success: res => {
if (res.cancel) return;
// 安装包下载
if (isiOS) {
plus.runtime.openURL(url);
return;
}
...
}
});
}
User cancels download
https://uniapp.dcloud.net.cn/api/request/network-file.html#downloadfile
var downloadTask = uni.downloadFile({
url: 'https://www.example.com/file/test', //仅为示例,并非真实接口地址。
complete: ()=> {
}
});
downloadTask.abort();
How to package wgt resource bundle
1. Change manifest.json
the application version name and application version number in the project
2. HBuilderX>Publish>Native App-Make application wgt package>
OK It will appear WGT安装包中manifest.json文件的version版本不匹配
, the update effect cannot be tested locally
How to view wgt file manifest.json
After the wgt package is generated, it will be .wgt
the suffix name, change the suffix name .zip
, and then decompress it, you can view manifest.json
it
Error resolution: The version version of the manifest.json file in the WGT installation package does not match
manifest.json
The version in is greater than or equal to the online version, you can check it yourself
Upload the wgt resource package through uni-admin
uni-admin error solution: super administrator already exists
It is because the admin account is old and does not match the appid. Delete the old admin account and create it again.