真正有效的本地app版本号只能通过plus.runtime.version获取,它对应manifest.json的versionname;需用#ifdef app-plus条件编译、try/catch容错,并fallback至uni.getsysteminfosync().version加正则校验。

怎么拿到真正有效的本地App版本号
别用 uni.getSystemInfoSync().version —— 它在 iOS 返回 Bundle Version,在 Android 可能为空或返回系统版本,完全不可靠。真机上唯一可信的是 plus.runtime.version,它对应 manifest.json 里填的 versionName(如 "2.8.0")。
但要注意三点:
-
plus对象仅在#ifdef APP-PLUS编译环境下存在,H5/小程序里会报错,必须加条件编译包裹 - 模拟器里
plus可能为undefined,真机调试才有效 - 得用
try/catch包一层,低端安卓机或某些定制 ROM 下plus.runtime可能未注入
兜底逻辑建议:先取 plus.runtime.version,失败则 fallback 到 uni.getSystemInfoSync().version,再用正则 /^\d+\.\d+\.\d+$/ 校验格式,不合法就跳过本次比对。
服务端返回的版本怎么比才不会错
字符串直接比较 "2.10.0" > "2.9.0" 是 false,语义错误。必须用语义化比对函数。
uni.compareVersion(a, b) 是官方推荐方案,返回 -1(a 0(相等)、1(a > b),但前提是两端版本格式严格一致。
服务端接口必须返回纯语义化字符串(如 "2.9.0"),禁止混用:"v2.9.0"、2.9(数字)、"2.9.0-build123"。
常见错误:
- 服务端返回
version_code: 102(整数),客户端却拿plus.runtime.version(字符串"2.9.0")去比 → 类型不匹配,结果不可控 - 客户端传了
"2.9.0"给服务端,服务端返回"2.9"→ 长度不同,compareVersion会按位截断,导致误判
强制更新弹窗为什么拦不住用户
不是弹窗样式问题,是控制流没卡住。用户点「取消」或按返回键后,如果首页继续加载数据、发起 API、渲染 tabbar,那就等于强制更新彻底失效。
正确做法是路由守卫 + 全局状态:
- 检测到需强制更新时,立刻
uni.setStorageSync('pendingUpdate', true) - 所有页面
onLoad开头加判断:if (uni.getStorageSync('pendingUpdate')) { uni.redirectTo({ url: '/pages/update/force' }); return; } - 在
/pages/update/force页面里只渲染全屏弹窗(必须用<cover-view></cover-view>,普通<view></view>会被 map/video 盖住)
Android 物理返回键要单独拦截:#ifdef APP-PLUS 里用 plus.key.addEventListener('backbutton', ...),把返回行为重定向为“重新弹窗”或 uni.showToast 提示,不能放行。
下载安装阶段最容易踩的硬坑
Android 和 iOS 完全是两套逻辑,不能共用一套代码路径。
Android:
- 下载必须用
uni.downloadFile,路径只能是uni.env.USER_DATA_PATH或uni.env.TEMP_FILE_PATH,拼/sdcard/xxx.apk在 Android 10+ 静默失败 - Android 11+ 必须在
androidmanifest.xml声明android:requestLegacyExternalStorage="true",否则写入失败报fail permission denied - 安装前建议校验 MD5,服务端必须提供
file_md5字段,避免用户装上半截损坏包
iOS:
-
uni.installApk在 iOS 下无任何效果,别调 - 只能跳转
itms-services://?action=download-manifest&url=xxx.plist,而该plist必须由企业证书签名,且托管在 HTTPS 域名下 - 个人开发者无法走此路径,只能跳 App Store:
https://apps.apple.com/app/id{appid}
最常被忽略的一点:冷启动(onLaunch)才可靠,热更新或后台切前台时 onLaunch 不执行。必须同时监听 onShow,且加节流(比如 5 分钟内只查一次),否则用户从微信切回来,你根本没机会提示。











