原文链接:uni-app整包更新与热更新方案(安卓和IOS)
效果预览
大致效果:
打开App,进入首页(首次),检测线上是否存在新版本,如果存在,弹窗提示用户是否进行版本更新。Android 有热更新和整包更新,若为热更新,更新完会自动重启;若为整包更新,则进入浏览器(如果上架了应用市场,对应逻辑可以写成跳转到应用市场)进行下载。ios 则只能跳转到App Store进行更新。
如果用户点了取消按钮,在使用 App 的过程中不会再进行弹窗提示,等到用户下次进入 App 才会重新提示。
步骤
客户端版本管理
字段 | 解释 |
---|---|
更新包名称 | 更新包名称,例如:HK-IOS-1.0.0 |
更新包文件 | 上传的 apk、ipa、wgt 文件 |
更新包版本号 | 更新包版本号,必须大于上一次更新的版本号 |
客户群体 | 1 普通用户 、 2 会员 |
更新包类型 | ANDROID 、 IOS |
更新类型 | 否 、 整包更新 、 热更新 |
发行地区 | 港澳台 、 印尼 、 大陆 |
更新包描述 | zh(中文) 、 en(英文) 、 in(印尼语) |
这里的字段可根据自己的需求进行设计。
APP
version 组件
<template>
<view class="tzy-version">
<u-modal
:value="updateVsb"
:title="$t('version.versionUpdateTips')"
:show-cancel-button="isShowCancelBtn"
:cancel-text="$t('btn.cancel')"
:confirm-text="$t('version.update')"
@cancel="cancelUpdate"
@confirm="updateConfirm">
<view class="version-online">V {{ updateObj.version }}</view>
<view class="model-version" slot-name="content">
<scroll-view scroll-y="true" class="content-text">
<view class="content-text">
<u-input
v-model="targetDesc"
type="textarea"
:border="false"
:disabled="true"
:auto-height="true"
:customStyle="{ 'font-size': '14px', color: '#96a0b5',
'word-break': 'break-word !important' }"
/>
</view>
</scroll-view>
</view>
</u-modal>
</view>
</template>
<script>
import config from '@/common/js/config.js';
import phoneInfo from '@/common/js/phone-info.js';
export default {
props: {
// 页面来源
pageFrom: {
type: String,
default: 'Home'
},
// 是否显示弹窗
updateVsb: {
type: Boolean,
default: false
},
// 是否显示取消按钮
isShowCancelBtn: {
type: Boolean,
default: true
},
updateObj: {
type: Object,
default: () => {}
},
targetDesc: {
type: String,
default: ''
}
},
methods: {
cancelUpdate() {
if (this.pageFrom == 'Home') {
uni.setStorageSync('cancelUpdate', 'true');
}
this.$emit('cancelClickEvent');
},
updateConfirm() {
// 下载更新包
const platform = phoneInfo.systemInfo.platform.toLowerCase();
const url = config.uploadUrl + this.updateObj.url;
const type = this.updateObj.type;
// type仅为我司定义
if (type == 1) {
this.$emit('cancelClickEvent');
uni.setStorageSync('cancelUpdate', 'true');
uni.setStorageSync('widgetInfo', {});
// 整包
if (platform == 'android') {
// 安卓打开网页下载
plus.runtime.openURL(url);
} else {
// ios打开应用商店 https://appstoreconnect.apple.com/
// apple id 在 app conection 上传的位置可以看到
const appleId = 'xxxxxx'; // 这里替换成你的 apple id
plus.runtime.launchApplication({
action: `itms-apps://itunes.apple.com/cn/app/id${appleId}?mt=8`
},
function(e) {
console.log('Open system default browser failed: ' + e.message);
}
);
}
} else if (type == 2) {
//热更新
console.log('热更新。。。。。。。。', url);
plus.nativeUI.showWaiting(this.$t('dataDesc.updating'));
uni.downloadFile({
url: url,
success: downloadResult => {
if (downloadResult.statusCode === 200) {
plus.runtime.install(
downloadResult.tempFilePath, {
force: false
},
function() {
console.log('install success...');
plus.nativeUI.closeWaiting();
// 更新版本信息
uni.setStorageSync('widgetInfo', {});
plus.runtime.restart();
},
function(e) {
console.error('install fail...');
plus.nativeUI.closeWaiting();
}
);
}
},
fail: error => {
console.log(error);
}
});
}
}
}
};
</script>
<style lang="scss" scoped>
.version-online {
text-align: center;
font-size: 14px;
font-weight: 600;
margin-top: 10px;
}
.content-text {
max-height: 280px;
}
.model-version {
padding: 12px 24px 30px;
font-size: 14px;
color: $cat_text_normal;
}
.desc-font {
font-size: 14px !important;
color: #96a0b5 !important;
word-break: break-all !important;
}
</style>
首页中引用 version 组件
<template>
<view>
<!-- 热更新组件 仅APP显示-->
<!-- #ifdef APP-PLUS -->
<versionUpdate
pageFrom="Home"
:updateVsb="updateVsb"
:updateObj="updateObj"
:targetDesc="targetDesc"
@cancelClickEvent="cancelClickEvent">
</versionUpdate>
<!-- #endif -->
</view>
</template>
<script>
import { clientVersionQuery } from '@/api/client.js';
import versionUpdate from '@/components/muudah-version/index.vue';
export default {
name: 'Home',
components: {
versionUpdate
},
data() {
return {
updateObj: {
url: '',
type: '',
version: ''
},
updateVsb: false,
targetDesc: '', // 版本更新描述
};
},
methods: {
getUpdate() {
//当前版本号 转化为数字
const tar_version = versionToNum(phoneInfo.manifestInfo.version);
// android || ios
const platform = phoneInfo.systemInfo.platform.toLowerCase() == 'ios' ? 'IOS' : 'ANDROID';
const version_to = this.versionTo; // 发行地区
// 这里调接口 是否检测到版本更新
clientVersion({
client_type: platform,
client_area: version_to
}).then(res => {
const {
Code,
data,
sdk_path
} = res;
if (Code == 0 && sdk_path != '' && data.client_version != '') {
// 线上的版本 转化为数字
const versin_online = versionToNum(data.client_version);
if (versin_online > tar_version && data.update_status > 0) {
this.updateObj.url = sdk_path;
this.updateObj.type = data.update_status;
this.updateObj.version = data.client_version;
// "update_status": 更新类型. 0: 否, 1: 整包更新, 2: 热更新
const desc_str = eval('(' + data.desc + ')');
// 这里根据语言包显示语言
this.targetDesc = desc_str[this.language];
this.updateVsb = true;
}
}
});
},
cancelClickEvent() {
this.updateVsb = false;
}
}
}
</script>
APP.vue
<script>
import phoneInfo from '@/common/js/phone-info.js'; // 这里面保存了 设备的基本信息
export default {
onLaunch: function() {
// 获取设备基本信息
uni.getSystemInfo({
success: res => {
phoneInfo.systemInfo = res;
}
});
// #ifdef APP-PLUS
plus.screen.lockOrientation('portrait-primary'); //锁定屏幕方向
uni.setStorageSync('cancelUpdate', 'false'); // 进来APP 重置更新弹窗
// 获取App 当前版本号
if (Object.keys(uni.getStorageSync('widgetInfo')).length == 0) {
plus.runtime.getProperty(plus.runtime.appid, widgetInfo => {
phoneInfo.manifestInfo = widgetInfo;
uni.setStorageSync('widgetInfo', widgetInfo);
});
}
//#endif
}
};
</script>
最后,你还可以尝试了解 App升级中心 uni-upgrade-center 。