DCloud_UNI_CHB
DCloud_UNI_CHB
  • 发布:2018-08-30 18:40
  • 更新:2024-04-25 15:31
  • 阅读:172826

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。

  1. 把apk存放到uniCloud的cdn上,可以免费使用
  2. 有现成的插件,不用写升级逻辑,打好安装包,发布管理,检查升级都可以直接用,详见: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如下:

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、更新包地址等)

实现示例:

  1. 【推荐】通过uniCloud的云函数模板,快速实现升级检查逻辑,详情参考:https://ext.dcloud.net.cn/plugin?id=4470
  2. php示例代码:
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;

常见问题

  1. 版本检测需要打包app,真机运行基座无法测试。因为真机运行的plus.runtime.version是固定值。
47 关注 分享
Trust 2***@qq.com c***@126.com dev7 水灵退散 wzl16 DCloud_UNI_CHB 没得好名字 [已删除] 1***@qq.com 沧桑 1***@qq.com sonicsunsky wuguangyong CodeIsLaw 草灯 1***@qq.com 6***@qq.com 3***@qq.com Iain s***@163.com 江西来客 3***@qq.com 知行合一 3***@qq.com ai666 w***@163.com x***@163.com 1***@qq.com 奶凶的喵咪 dyjx2004 5***@qq.com 小胖子783 1***@qq.com 5178008pp 2***@qq.com d***@163.com 柠檬七喜 1***@qq.com chentiaotiao 786395613 rysnone 1***@qq.com 4***@qq.com 1***@qq.com WEISENB j***@163.com

要回复文章请先登录注册

dyjx2004

dyjx2004

回复 8***@qq.com :
非要写在前端的话 就是 \r\n 好像是换行
2020-07-16 17:40
dyjx2004

dyjx2004

回复 8***@qq.com :
后端使用textarea存入数据库 就可以换行 然后再从api调用就行了
2020-07-16 17:38
8***@qq.com

8***@qq.com

回复 5***@qq.com :
我也是这个问题 有什么好的解决方法么 app.vue里又不能使用 弹窗组件
2020-07-16 15:14
n***@126.com

n***@126.com

整包升级能不能也类似热更新的方式来,只不过是apk,检测是否需要更新通过plus.runtime.install安装?
2020-05-18 18:07
黑白狼

黑白狼

回复 1***@qq.com :
plus.runtime.getProperty(plus.runtime.appid, function(widgetInfo) {

plus.nativeUI.toast(plus.runtime.appid);

plus.nativeUI.toast(widgetInfo.version);
2020-05-06 16:08
gotogether

gotogether

啥时候整包更新和热更新能做成apicloud那样,后台配置的
2020-05-06 11:34
1***@qq.com

1***@qq.com

我在调试过程中用 plus.runtime.version;获取到的版本号是9.6.88 ,plus.runtime.appid获取到的是HBuilder,怎么才能准确的获取到APP的版本号,我要拿上一次的版本号和这次的做对比,然后判断是否更新,现在是怎么都会提示让更新
2020-04-18 16:20
1***@qq.com

1***@qq.com

用这种方法下载,下载完然后提示安装
appUpdate({commit},app){
global.post("/Admin/App/Update", { appid: app.appid, version: app.version })
.then(obj => {
if (obj.status === 200 && obj.data.status == 1) {
uni.showModal({ //提醒用户更新
title: "Update tips",
content: obj.data.note,
showCancel:false,
success: (res) => {
if (res.confirm) {
//plus.runtime.openURL(obj.data.url);
plus.nativeUI.toast("正在准备环境,请稍后!");
var dtask = plus.downloader.createDownload(obj.data.url, { method: 'GET', filename: '_doc/update/' }, function(d, status) {
if(status == 200) {
var path = d.filename; //下载apk
plus.runtime.install(path); // 自动安装apk文件
} else {
plus.nativeUI.alert('版本更新失败:' + status);
}
});
dtask.start();
}
}
})
}
})
}
2020-04-15 15:59
叶凌风

叶凌风

回复 叶凌风 :
写错了,应该是!=
2020-04-09 17:24
叶凌风

叶凌风

if ($version !== "1.0.1") 应该用==这样有空格的话就惨了
2020-04-09 17:23