uni-app 整包升级/更新方案

发布于 1周前 作者 bupafengyu 来自 Uni-App

uni-app 整包升级/更新方案

官方已发布APP升级中心,支持原生APP整包升级和wgt资源包升级,我们强烈推荐您使用,详见 https://uniapp.dcloud.io/uniCloud/upgrade-center

如下是官方APP升级中心发布之前的文章,供老用户参考,新用户推荐使用 https://uniapp.dcloud.io/uniCloud/upgrade-center

使用 uni-app 开发,可将代码编译到iOS、Android、微信小程序等多个平台,升级时也需考虑多平台同步升级。

uni-app发布为小程序的升级模式较简单,只需将开发完的代码提交小程序后台,待审核通过后用户将自动升级。

App端的升级,又分为整包更新和资源热更新两种。

  • 整包更新,即常规的整个App安装包重新下载安装。
  • 资源热更新,即App并重新安装,里面的js等前端代码进行更新。

资源热更新另见文档:http://ask.dcloud.net.cn/article/35667

本文重点讲解整包更新。

一般iOS Appstore的安装包,无法直接更新。App启动后检查有新版本,只能调整到Appstore,然后用户在Appstore的详情页点击更新按钮。

而Android App,可以直接下载新的apk,只要包名和证书不变,就可以覆盖安装。

App升级,强烈推荐使用uniCloud。

  • 把apk存放到uniCloud的cdn上,可以免费使用。
  • 有现成的插件,不用写升级逻辑,打好安装包,发布管理,检查升级都可以直接用,详见:https://ext.dcloud.net.cn/plugin?id=4470

如果不使用uniCloud,自己也可以写升级逻辑,下文讲解了常见的逻辑,但下文不是DCloud约定的强制逻辑,只是一般性常见做法的介绍。

接口约定

如下数据接口约定仅为示例,开发者可以自定义接口参数。

请求地址:https://www.example.com/update

请求方法:GET

请求数据:

{
    "appid": plus.runtime.appid,
    "version": plus.runtime.version
}

响应数据:

{
    "status":1,//升级标志,1:需要升级;0:无需升级
    "note": "修复bug1;\n修复bug2;",//release notes
    "url": "http://www.example.com/uniapp.apk" //更新包下载地址
}

客户端实现

App启动时,向服务端上报当前版本号,服务端判断是否提示升级。

在App.vue的onLaunch中,发起升级检测请求,如下:

onLaunch: function () {
    //#ifdef APP-PLUS
    var server = "https://www.example.com/update"; //检查更新地址
    var req = { //升级检测数据
        "appid": plus.runtime.appid,
        "version": plus.runtime.version
    };
    uni.request({
        url: server,
        data: req,
        success: (res) => {
            if (res.statusCode == 200 && res.data.status === 1) {
                uni.showModal({ //提醒用户更新
                    title: "更新提示",
                    content: res.data.note,
                    success: (res) => {
                        if (res.confirm) {
                            plus.runtime.openURL(res.data.url);
                        }
                    }
                })
            }
        }
    })
    //#endif
}

注意:App的升级检测代码必须使用条件编译,否则在非App环境由于不存在plus相关API,将会报错。

升级地址URL,如果是自行托管的App,就提供自己的包地址。如果是打开应用市场,那URL如下:

```javascript
if (plus.os.name=="Android") {
    appurl = "market://details?id=io.dcloud.hellouniapp"; //这个是通用应用市场,如果想指定某个应用商店,需要单独查这个应用商店的包名或scheme及参数
}
else{
    appurl = "itms-apps://itunes.apple.com/cn/app/hello-uni-app/id1417078253";
}

服务端实现

根据客户端上报的版本号,比对服务端最新版本号,决定是否需要升级,若需升级则返回升级信息(rease notes、更新包地址等)

实现示例:

header("Content-type:text/json");
$appid = $_GET["appid"];
$version = $_GET["version"]; //客户端版本号
$rsp = array("status" => 0); //默认返回值,不需要升级
if (isset($appid) && isset($version)) {
    if ($appid === "__UNI__123456") { //校验appid
        if ($version !== "1.0.1") { //这里是示例代码,真实业务上,最新版本号及relase notes可以存储在数据库或文件中
            $rsp["status"] = 1;
            $rsp["note"] = "修复bug1;\n修复bug2;"; //release notes
            $rsp["url"] = "http://www.example.com/uniapp.apk"; //应用升级包下载地址
        }
    }
}
echo json_encode($rsp);
exit;

常见问题

  • 版本检测需要打包app,真机运行基座无法测试。因为真机运行的plus.runtime.version是固定值。

1 回复

针对uni-app整包升级/更新方案,我们可以利用uni-app提供的相关API以及服务器端配合,实现应用的版本检测、下载更新包以及安装更新的功能。以下是一个简要的实现思路和代码案例:

1. 服务器端配置

首先,需要在服务器端配置一个接口,用于返回当前最新版本的信息以及下载链接。例如,我们可以使用Node.js和Express来搭建一个简单的服务器:

const express = require('express');
const app = express();
const port = 3000;

app.get('/api/version', (req, res) => {
    const latestVersion = '1.2.3'; // 最新版本号
    const downloadUrl = 'https://example.com/path/to/your/app.apk'; // 下载链接
    res.json({
        version: latestVersion,
        downloadUrl: downloadUrl
    });
});

app.listen(port, () => {
    console.log(`Server running at http://localhost:${port}/`);
});

2. 客户端实现

在uni-app的客户端,我们需要实现版本检测、下载更新包以及提示用户安装的功能。以下是一个简单的实现示例:

// 在app.vue的onLaunch方法中检测版本
onLaunch() {
    uni.request({
        url: 'http://localhost:3000/api/version', // 替换为你的服务器地址
        success: (res) => {
            const { version, downloadUrl } = res.data;
            const currentVersion = '1.2.2'; // 当前应用版本号

            if (compareVersions(currentVersion, version) < 0) {
                uni.showModal({
                    title: '版本更新',
                    content: '发现新版本,是否立即更新?',
                    success: (result) => {
                        if (result.confirm) {
                            downloadAndUpdate(downloadUrl);
                        }
                    }
                });
            }
        }
    });
},

methods: {
    compareVersions(v1, v2) {
        // 简单的版本比较函数
        const arr1 = v1.split('.');
        const arr2 = v2.split('.');
        for (let i = 0; i < Math.max(arr1.length, arr2.length); i++) {
            const num1 = parseInt(arr1[i] || 0);
            const num2 = parseInt(arr2[i] || 0);
            if (num1 > num2) return 1;
            if (num1 < num2) return -1;
        }
        return 0;
    },
    downloadAndUpdate(url) {
        // 下载并安装更新包(注意:此部分在不同平台实现方式可能不同,以下仅为示例)
        const task = uni.downloadFile({
            url: url,
            success: (res) => {
                // 根据平台不同,执行相应的安装操作
                // 例如,在Android上,可能需要引导用户到下载管理界面手动安装
                // 在iOS上,则可能需要通过App Store更新
            },
            fail: (err) => {
                console.error('下载失败', err);
            }
        });

        task.onProgressUpdate((res) => {
            console.log('下载进度', res.progress);
        });
    }
}

以上代码提供了一个基本的整包升级/更新方案的实现思路,包括版本检测、下载更新包以及提示用户安装更新。请注意,不同平台(如Android和iOS)在下载和安装更新包的具体实现上可能有所不同,需要根据实际情况进行调整。

回到顶部