Write the Code. Change the World.

11月 10

要实现 app 内版本更新得走以下几个流程:

  1. 对系统的获取(android 或 ios)。

  2. 对系统当前 app 版本的获取(1.0.1 + '.' + 100)(版本名称 + 版本号控制)。

  3. 对服务端接口请求 app 版本信息(定义当前最新版本号)。比如 app 之前的版本是 1.0.1.100,返回给前端就是这个。后来你新提交了一个版本 1.0.2.100,并审核通过了。当审核通过时,你修改后端配置,将版本号改成 1.0.2.100,这个时候返回前端就是 1.0.2.100。

  4. 用当前 app 版本信息和服务端版本信息进行对比。如果不一样,则表示服务端有新的版本。应弹窗提示用户进行 app 更新。(版本可以定义两个,android 和 ios 各一个,每个系统同一时间可能会不一样)。

  5. 弹窗提示用户是否要更新。用户点击确定。如果是 ios 系统,则跳转到商店更新(亲自测试可行)。如果是 android 系统,则下载安装包更新(没亲测过),ios 是必须要走商店,且只有一个商店,比较好弄,也正规。android 打个包就可以装,上商店也很多家都可以。说它简单是只要个正常的包就可以装,说它不简单就是商店太多,审核太麻烦,还得要软著,太心累。一般不到万不得已,根本就不想上 android 商店。

上边这个流程是在客户端做判断,并去处理升级。感觉不太好,因为客户端一旦上架你短时间内很难修改和改变。如果把判断放在服务端,你可以随时随地的修改。以备异常情况。(也是文章写着写着,想法也就变了)

运行环境管理对象(获取版本信息等能力)

官方文章

App升级中心

虽然 uniapp 官方提供了套件,但还是个人用户实现的更自由些(套件的升级 ui 界面 好像不能任意自定义)。

代码操作

一定要使用条件编译,也就是 app 才需要这样。因为有些 api 只有 app 端才有的。

// #ifdef APP-PLUS
# 从服务端获取 app 版本信息
GetAppVersion().then(res => {
   // 获取当前已安装的 app 的版本信息
    let curVersion = plus.runtime.version + '.' + plus.runtime.versionCode;
    let osName = uni.getSystemInfoSync().platform;
    if (osName == 'ios') {
        if (res.ios_version && res.ios_version != curVersion) {
            // 弹提示是否要更新。如果更新,就跳转到苹果应用商店
            uni.showModal({
                title: '更新提示',
                content: '发现新版本,是否要更新?',
                cancelColor: '#383838',
                confirmColor: '#ffc80b',
                success(res) {
                    if (res.confirm) {
                        let appleId = 6443910575;
                        plus.runtime.launchApplication(
                            {
                                action: `itms-apps://itunes.apple.com/cn/app/id${appleId}?mt=8`
                            },
                            function(e) {
                                console.log(e.message);
                            }
                        );
                    }
                }
            });
        }
    } else if (osName == 'android') {
        if (res.android_version && res.android_version != curVersion && res.downUrl) {
                // 弹窗提示是否要更新。如果更新,跳转到特定商店更新或下载更新。(弹窗省略了,去商店也省了)
                var downTask = plus.downloader.createDownload(url, {}, function(d, status) {
                //d为下载的文件对象
                if (status == 200) {
                    //下载成功,d.filename是文件在保存在本地的相对路径,使用下面的API可转为平台绝对路径
                    var fileSaveUrl = plus.io.convertLocalFileSystemURL(d.filename);
                    plus.runtime.openFile(d.filename); //选择软件打开文件
                    uni.showToast({
                        icon: 'none',
                        title: '更新成功'
                    })
                } else {
                    //下载失败
                    plus.downloader.clear(); //清除下载任务
                    uni.showToast({
                        icon: 'none',
                        title: '更新失败'
                    })
                }
            })
            //开始下载
            downTask.start();

            //监听下载进度
            downTask.addEventListener('statechanged', (task) => {
                let percentage = parseInt(
                    (parseFloat(task.downloadedSize) /
                        parseFloat(task.totalSize)) *
                    100
                );
                if (percentage == 100) {
                    // 更新完成
                }
            })
        }
    }
});
// #endif

上边仅供参考,实际情况需调试。后一个思路,由服务端判断是否要更新,并提供更新信息(下载地址,商店地址等)这种方式比较好。还有 android 这边如果自己做下载更新,还得做个好看的 ui 升级界面。有进度条显示那种。