App端获取版本号必须用条件编译#ifdef APP-PLUS调用plus.runtime.version,不可用uni.getSystemInfoSync().version等错误方式;比对需语义化函数,iOS强制更新须用正确itms-apps链接。

App端怎么拿到当前安装包的版本号
uni-app 在 App 端无法直接读取 manifest.json 里的 versionName,运行时要用原生能力。HBuilderX 3.1.0+ 提供了 uni.getSystemInfoSync().platform + 原生插件或条件编译调用,但最稳的方式是:在 App 启动时,通过 plus.runtime.version 获取真实安装包版本(仅 App 端有效)。
注意:uni.getAppBaseInfo() 或 uni.getSystemInfoSync().version 返回的是微信小程序基础库版本或 H5 UA 信息,不是 App 版本 —— 这个坑踩的人最多。
- 必须用条件编译:
#ifdef APP-PLUS包裹获取逻辑 -
plus.runtime.version是字符串,如"2.8.0",别误当成数字比较 - 真机调试才能拿到值,模拟器里
plus对象可能为undefined
怎么安全比对服务端返回的新版本号
服务端通常返回一个 JSON,比如 { "version": "2.9.0", "force": true, "downloadUrl": "https://..." }。比对不能简单用 >,因为 "2.10.0" > "2.9.0" 在字符串比较中是 false。
推荐用 uni-app 自带的 uni.upx2px 风格不适用,得自己写轻量版语义化比对函数,不依赖外部库:
function versionCompare(v1, v2) {
const s1 = v1.split('.').map(Number);
const s2 = v2.split('.').map(Number);
for (let i = 0; i n2) return 1;
if (n2 > n1) return -1;
}
return 0;
}
- 传入两个字符串,返回
1(v1 更高)、-1(v2 更高)、0(相等) - 避免用
parseFloat或正则提取数字,会丢掉1.9.10中的10 - 后端返回的
version必须严格遵循x.y.z格式,否则比对失效
弹窗逻辑里 force 更新要阻断用户所有操作
强制更新不是“点确定就跳应用市场”,而是必须让用户完成升级动作才能继续使用 App —— 这意味着不能只靠 uni.showModal,得用全屏遮罩 + 禁用底层页面交互。
常见错误是弹窗后用户还能点 TabBar、下拉刷新、甚至跳路由,本质是没锁住 page 的事件流。
- 用
position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 9999;盖住整个视口 - 弹窗组件内监听
touchmove并preventDefault,防穿透滚动 - 不要用
uni.navigateTo跳转下载页,改用plus.runtime.openURL(downloadUrl)或唤起内置浏览器 - Android 上若用
intent安装 APK,需额外申请REQUEST_INSTALL_PACKAGES权限(HBuilderX 3.6.0+ 可在manifest.json → Android 设置勾选)
为什么 iOS 上 force 更新经常失败
iOS 不允许 App 内直接安装新包,force: true 在 iOS 上实际只能跳转 App Store 页面。但很多人卡在:点了“立即更新”没反应,或者跳转后找不到对应页面。
根本原因是 Apple 的链接规则太死:必须用 itms-apps://apps.apple.com/cn/app/xxx/id123456789 格式,且 id 必须和当前 App 的 Bundle ID 完全匹配,大小写敏感。
- 别拼错
itms-apps://(不是https://,也不是itms://) - Bundle ID 要从 Xcode 工程里确认,不是 manifest 里填的
id字段 - App Store 页面未上架或审核中时,跳转会白屏或报错
Cannot connect to iTunes Store,前端没法捕获,只能提前灰度验证 - 上线前务必用 TestFlight 打个包,真机测试跳转链路是否通
版本号比对本身不难,难的是每个平台的限制都得单独兜住 —— 尤其是 iOS 的跳转、Android 的权限、还有热更新和离线包共存时的版本优先级,这些地方一漏,用户就卡在启动页动不了。











