Uniapp实现App版本自动升级功能教程与实践指南

2024-12-15 0 888

在App开发环节,版本自动更新是至关重要的一个环节。尽管官方提供了支持,但管理起来却颇为繁琐,存在不少难点。因此,众多开发者倾向于自行实现版本自动更新,这其中包含了许多值得深入讨论的问题。

前端实现方式

前端自动升级对用户感受影响显著。通过在.js和App.vue中调用更新检查,是一种实现方式。以小型项目为例,比如我2019年加入的那个5人团队开发的项目,由于前期规划不足,导致后续版本更新时界面出现了短暂的闪烁。这不仅是技术上的问题,更凸显了前端实现中细致规划的重要性。再比如,某款新兴App的前端版本更新设计得相当出色,用户几乎察觉不到更新过程。

在开发过程中,前端代码的简洁性同样关键。代码若过于繁杂,会使加载和更新速度减慢。特别是一些大型服务类应用,在高峰时段,前端更新若占用过多资源,将严重影响用户体验。

后端实现的关键

后端在版本自动升级过程中扮演着关键角色。我的后端表格设计得较为简单,操作上确实便于版本回退。之前曾负责一个电商App的版本管理,当时设计的后端版本管理表格,每个字段都十分明确,比如版本号、更新时间、更新内容概要等。相应的SQL语句编写起来十分明了,便于查询和修改,能快速找到所需信息。基于这样的基础,增加一个查询当前版本的接口便变得容易多了。

后端设计不能太简单。曾经有一款社交App,因为后端版本管理不够复杂,在更新时出现了数据丢失的问题。2022年的一次大更新,由于缺乏细致的版本管理操作(创建、读取、更新、删除),导致一些用户信息关联出现了错误。

import request from "@/utils/common.js";
import config from '../config.js'
function check(param = {}) {
    // 合并默认参数
    param = Object.assign({
        title: "检测到有新版本!",
        content: "请升级app到最新版本!",
        canceltext: "暂不升级",
        oktext: "立即升级"
    }, param)
    plus.runtime.getProperty(plus.runtime.appid, (widgetInfo) => {
        let platform = plus.os.name.toLocaleLowerCase()
        request.request('/app/versionConfig/getCurrent', {}, 'get', function (result) {
            let data = result.data ? result.data : null;
            if (widgetInfo.version === data.versionCode) {
                return;
            }
            if (result.code == 200) {
                if (platform == 'ios') {
                    // 如果是ios,则跳转到appstore
                    plus.runtime.openURL(result.data.data.url)
                    return;
                }
                // android进行如下操作
                uni.showModal({
                    title: param.title,
                    content: data.log ? data.log : param.content,
                    showCancel: data.force ? false : true,
                    confirmText: param.oktext,
                    cancelText: param.canceltext,
                    success: res => {
                        if (!res.confirm) {
                            console.log('取消了升级');
                            plus.runtime.quit();
                        }
                        if (data.shichang === 1) {
                            //去应用市场更新
                            plus.runtime.openURL(data.shichangurl);
                            plus.runtime.restart();
                        } else {
                            // 清除缓存
                            request.clearLogin();
                            // 开始下载
                            // 创建下载任务
                            var dtask = plus.downloader.createDownload(config.baseUrl + data.versionUrl, {
                                    filename: "_downloads/"
                                },
                                function (d, status) {
                                    // 下载完成
                                    if (status == 200) {
                                        plus.runtime.install(d.filename, {
                                            force: true
                                        }, function () {
                                            //进行重新启动;
                                            plus.runtime.restart();
                                        }, (e) => {
                                            uni.showToast({
                                                title: '安装升级包失败:' + JSON
                                                    .stringify(e),
                                                icon: 'none'
                                            })
                                        });
                                    } else {
                                        this.tui.toast("下载升级包失败,请手动去站点下载安装,错误码: " +
                                            status);
                                    }
                                });
                            let view = new plus.nativeObj.View("maskView", {
                                backgroundColor: "rgba(0,0,0,.6)",
                                left: ((plus.screen.resolutionWidth / 2) - 45) +
                                    "px",
                                bottom: "80px",
                                width: "90px",
                                height: "30px"
                            })
                            view.drawText('开始下载', {}, {
                                size: '12px',
                                color: '#FFFFFF'
                            });
                            view.show()
                            dtask.addEventListener("statechanged", (e) => {
                                if (e && e.downloadedSize > 0) {
                                    let jindu = ((e.downloadedSize / e.totalSize) *
                                        100).toFixed(2)
                                    view.reset();
                                    view.drawText('进度:' + jindu + '%', {}, {
                                        size: '12px',
                                        color: '#FFFFFF'
                                    });
                                }
                            }, false);
                            dtask.start();
                        }
                    }
                })
            }
        })
    });
}
export default {
    check
}

云端云函数的考量

官方推出的应用升级服务,其核心是依托云端的云函数技术。这种做法看似便捷,实则给项目增添了额外的服务端负担。我之前参与过一个企业级应用的开发,就使用了这种云函数技术。结果发现,我们不仅要管理主服务端,还得持续关注云函数服务端的状态。举例来说,如果云函数服务端出现故障——比如2021年就曾发生过这样的情况——那么整个App的版本升级就会受到影响,进而减缓用户获取最新版本的速度。

<script>
    import checkappupdate from 'common/checkappupdate.js'
    
    export default {
        onLaunch: function () {
            checkappupdate.check({
                title: '检测到有新版本!',
                content: '请升级app到最新版本!',
                canceltext: '暂不升级',
                oktext: '立即升级'
            });
        }
    }
</script>

云函数的费用同样不容忽视,特别是对于预算有限的创业项目来说,这些费用每月累积起来,数额相当可观。

自定义版本升级的优势

自定义版本的自动更新给实际开发带来了诸多便利。其中,便于调整是一个关键因素。以我之前开发的一个工具类App为例,随着功能的持续扩展,每次更新都需要对不同的地方进行修改。这时,自定义版本的升级功能就能迅速调整更新逻辑。例如,在新增功能时,我们只需对相关功能的版本更新进行特定的代码处理。

减少对云函数的依赖,相应地降低了故障风险。以校内自用的管理App为例,升级到自定义版本后,由于学校网络环境相对稳定,很少因外部服务端问题而影响升级流程。

自定义版本升级虽非易事,文中指出模块代码调整可能较为复杂。这亦是众多开发者常遇的挑战。以2020年对一款阅读App进行自定义升级为例,针对安卓系统进行了版本更新,却发现在iOS系统上出现显示故障,不得不进行大量代码调试。

Uniapp实现App版本自动升级功能教程与实践指南

多设备兼容性存在难题,手机和平板等设备因尺寸不同,对升级后界面的展示效果有不同要求,为此,必须投入大量精力确保定制版在各设备上都能顺畅运行。

展望App版本升级的发展

移动应用市场持续壮大,App的更新方法也在持续优化。未来,对更智能的版本升级的需求将会上升。比如,有些App已经开始尝试根据用户的使用习惯来推送个性化的版本更新。比如视频类App,若发现用户常看高清视频,新版本升级时会优先推送相关的高清内容。开发者面临选择:是继续探索更优的自定义升级方式,还是尝试官方或其他新的升级模式?欢迎读者在评论区发表意见,并点赞及转发本文。

drop table if exists biz_version_config;
/*==============================================================*/
/* Table: biz_version_config                                     */
/*==============================================================*/
create table biz_version_config
(
   id                   int(11) not null auto_increment comment '主键',
   version_code         varchar(255) comment '版本号',
   version_url          varchar(255) comment '下载地址',
   version_remark       varchar(255) comment '版本备注',
   is_current           int(11) comment '当前版本 1-是 2-否',
   create_by            varchar(64) default '' comment '创建者',
   create_time          datetime comment '创建时间',
   update_by            varchar(64) default '' comment '更新者',
   update_time          datetime comment '更新时间',
   status               tinyint(1) comment '状态 1-正常2-删除',
   primary key (id)
)
ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COMMENT = 'app版本配置' ROW_FORMAT = Dynamic;
alter table wm_version_config comment 'app版本配置';

申明:本文由第三方发布,内容仅代表作者观点,与本网站无关。对本文以及其中全部或者部分内容的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。本网发布或转载文章出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,也不代表本网对其真实性负责。

七爪网 行业资讯 Uniapp实现App版本自动升级功能教程与实践指南 https://www.7claw.com/2802840.html

七爪网源码交易平台

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务