最近使用uniapp框架开发了一款APP,怎么让APP监测到有新的版本,并且点击新的版本实现自动升级呢,话不多说,请看下文。
封装一个弹窗组件,当监测到最新的APP版本高于现在的版本时,弹窗提示新的版本信息,包括版本号、版本更新内容、是否强制更新控制等。
一、src/components/updateModal/index.vue,template代码如下:
<template>
<view>
<uni-popup
class="popup-wrap"
:is-mask-click="!versionObj.forceUpdate"
ref="popup"
type="center"
background-color="#fff"
>
<view class="popup-content-wrap">
<view class="title">New version detected</view>
<view class="content">
<view class="version-no">version: v {{ versionObj.version }}</view>
<view>Update content:</view>
<rich-text :nodes="versionObj.releaseNotes"></rich-text>
</view>
<view class="btn-wrap">
<view @tap="close" v-if="!versionObj.forceUpdate" class="cancel">cancel</view>
<view @tap="ok" class="confirm">confirm</view>
</view>
</view>
</uni-popup>
<!-- Android APP下载更新进度条弹窗 -->
<uni-popup
class="download-popup-wrap"
:is-mask-click="false"
ref="progressPop"
type="center"
background-color="#fff"
>
<view class="popup-content-wrap">
<view class="title">Downloading, please wait</view>
<view class="content">
<zui-progress-bar :value="percent" />
</view>
</view>
</uni-popup>
</view>
</template>
二、在mounted生命周期中,判断是否需要更新APP:
async mounted() {
// 获取最新版本入参
const versionParams = {
appId: config.systemAppId,
platform: this.systemInfo?.platform, // 全局状态里的平台字段
}
// 查询接口获取最新版本信息
const res = await versionsService.getLatestVersion(versionParams)
if (res.code === 200 && res.data) {
const version = res.data?.version
// 封装的checkVersion方法,拿到最新的版本信息(包括版本号、更新内容、是否强制更新)与现有版本号对比,判断是否需要更新
const needUpdate = checkVersion(version)
this.versionObj = res.data
// 需要更新弹窗提示
if (needUpdate) {
this.$refs.popup?.open()
}
}
},
三、弹窗提示,点击确认按钮开启更新
methods: {
ok () {
// 判断环境,区分不同的资源地址
const { VUE_APP_ENV } = config
const baseUrl =
VUE_APP_ENV === 'production'
? 'https://api.****.net'
: 'https://api-uat.***.net'
const that = this
// 获取手机是iOS系统还是Android系统
// 这里this.systemInfo是项目中设置的一个全局的系统状态
const platform = this.systemInfo?.platform
if (platform === 'android') {
// android端处理升级的逻辑
// 打开进度条弹窗
this.$refs.progressPop.open()
// 关闭APP版本更新信息弹窗
this.$refs.popup?.close()
// 对应的apk、ipa、plist文件已上传至文件资源服务器,上传文件的时候需要对应把版本号、版本更新信息作为入参一并传给后端
// 上传成功后会生成对应的版本id,前端拿到版本id然后拼接对应的文件路径、文件名称即可获得完整资源地址
// 以上建议读者自行开发一个对应的包版本管理的页面
// 使用uniapp的plus的api创建下载任务
const dtask = plus.downloader.createDownload(
`${baseUrl}/fileApi/***/${that.versionObj.versionId}/***.apk`,
{
filename: `_downloads/***{that.versionObj.version}.apk`,
},
function (d, status) {
if (status === 200) {
// 下载成功,使用plus api安装
plus.nativeUI.showWaiting('开始安装...')
plus.runtime.install(
d.filename,
{},
function () {
// 安装成功,数据初始化
uni.removeStorageSync('userInfo')
uni.removeStorageSync('state')
plus.nativeUI.closeWaiting()
that.$refs.progressPop.close()
},
function (e) {
plus.nativeUI.closeWaiting()
plus.nativeUI.alert(`安装失败[${e.code}]:${e.message}`)
that.$refs.progressPop.close()
}
)
} else {
plus.nativeUI.alert(`下载更新文件失败:${status}`)
that.$refs.progressPop.close()
}
}
)
// 监听下载任务的进度
dtask.addEventListener(
'statechanged',
function (d) {
that.percent = d.totalSize ? parseFloat(d.downloadedSize) / parseFloat(d.totalSize) : 0
// w.setTitle("已下载:" + (cur / (1024 * 1024)).toFixed(2) + "M/" + (total / (1024 * 1024)).toFixed(2) + "M");
},
false
)
dtask.start()
} else {
// ios处理逻辑,简单的多
// 拼接ios包资源地址,⚠️注意iOS系统中,是打开plist文件,plist文件内关联了最新的ipa文件,实现app更新
const url = `${baseUrl}/fileApi/***/${that.versionObj.versionId}/***.plist`
// 抵调用plus api打开itms-services协议的链接,即可下载更新
plus.runtime.openURL(
`itms-services://?action=download-manifest&url=${url}`,
(openURLres) => {
uni.removeStorageSync('userInfo')
uni.removeStorageSync('state')
console.log('openURLres:', openURLres)
}
)
}
}
}
四、这里补充一下plist文件内容,文件后缀是.plist
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- array of downloads. -->
<key>items</key>
<array>
<dict>
<!-- an array of assets to download -->
<key>assets</key>
<array>
<!-- software-package: the ipa to install. -->
<dict>
<!-- 必填项。 the asset kind. -->
<key>kind</key>
<string>software-package</string>
<!-- 必填项。App (.ipa) 文件的完全限定 HTTPS URL,经验证,这里可以支持http -->
<key>url</key>
<!-- 关联ipa文件 -->
<string>https://api-uat.***.net/fileApi/***/151/ipa/***.ipa</string>
</dict>
<!-- 57 x 57 像素的 PNG 图像,在下载和安装过程中显示。指定图像的完全限定 URL。经验证非必填项,但是官方说是必填项,而且有的话下载安装过程体验好些,所以最好有。 -->
<dict>
<key>kind</key>
<string>display-image</string>
<!-- optional. indicates if icon needs shine effect applied. -->
<key>needs-shine</key>
<true/>
<key>url</key>
<string>https://api-uat.***.net/***/image.57x57.jpg</string>
</dict>
<!-- 512 x 512 像素的 PNG 图像,表示 App Store 中相应的 App。经验证非必填项,但是官方说是必填项,酌情处理就好。 -->
<dict>
<key>kind</key>
<string>full-size-image</string>
<key>needs-shine</key>
<true/>
<key>url</key>
<string>https://api-uat.***.net/***/image.512x512.jpg</string>
</dict>
</array>
<key>metadata</key>
<dict>
<!-- 必填项。App 的包标识符,与 Xcode 项目中指定的完全一样 -->
<key>bundle-identifier</key>
<string>{包标识符}</string>
<!-- required. the download kind. -->
<key>kind</key>
<string>software</string>
<!-- optional. displayed during download; typically company name -->
<key>subtitle</key>
<string>{应用子名称}</string>
<!-- 必填项。下载和安装过程中显示的 App 的名称 -->
<key>title</key>
<string>{下载后显示的app名称}</string>
</dict>
</dict>
</array>
</dict>
</plist>
标签:uniapp,const,version,APP,更新,升级,api,plus
From: https://www.cnblogs.com/coderInside/p/17972197