关键在于“在哪调、怎么比、怎么装”:需条件编译+运行时双判断是否为App环境;版本比较须字符串分段或用versionCode;Android需权限声明并用openURL,iOS只能跳转TestFlight;wgt更新后必须restart,且下载用uni.downloadFile、链接须HTTPS。

直接对接应用内更新接口,关键不是“能不能调”,而是“在哪调、怎么比、怎么装”——plus.runtime 相关 API 只在真机 App 环境生效,H5 和小程序里调用会报错或静默失败。
必须先判断是否运行在 App 环境中
很多开发者一上来就写 uni.request + plus.runtime.getProperty,结果在 H5 或微信开发者工具里直接白屏或报 plus is not defined。正确做法是用条件编译 + 运行时双保险:
-
#ifdef APP-PLUS包裹所有原生逻辑,确保编译时剔除非 App 平台代码 - 运行时再用
typeof plus !== 'undefined'做二次兜底,避免某些调试场景漏掉 - 别依赖
uni.getSystemInfoSync().platform判断——它返回"android"或"ios",但 H5 也可能是"web",无法区分“是不是真 App”
版本号比较不能直接用数字解析
后端返回的 version(比如 "1.10.0")和本地 plus.runtime.version(比如 "1.2.0")若转成数字比较:1.10.0 > 1.2.0 === false,这是常见翻车点。
- 统一用字符串分段比较:用
.split('.')拆成数组,逐位转parseInt对比 - 或使用语义化版本库(如
semver),但注意 uni-app App 端不支持 npm 包直接引入,得手动 copy 核心逻辑 - 更稳妥的做法:后端额外返回一个单调递增的
versionCode(整数),前端只比这个字段,避免字符串解析歧义
安装 APK 或跳转 TestFlight 要处理权限和限制
Android 整包更新走 plus.runtime.openURL 打开下载链接后,用户点击安装,系统会弹权限申请;iOS 则根本不能直接安装 IPA,只能跳官方渠道。
- Android 必须在
manifest.json中声明"android.permission.REQUEST_INSTALL_PACKAGES",否则 8.0+ 系统会拦截安装意图 - iOS 无法调用任何安装 API,
plus.runtime.install对 IPA 无效,唯一合规路径是跳https://testflight.apple.com/或企业签名页(需已配置好对应 URL Scheme) - 别在
onLaunch里立刻弹窗——此时页面栈未就绪,uni.showModal可能被丢弃或触发闪退;应放在首页onShow后,且加个setTimeout延迟 300ms 再唤起
wgt 热更新要重启才生效
用 plus.runtime.install 安装 .wgt 包后,如果不调用 plus.runtime.restart(),新 JS/CSS/图片资源不会加载,用户看到的还是旧界面。
-
plus.runtime.restart()是必须步骤,不是可选项 - 重启前建议用
plus.nativeUI.toast提示“正在更新,请稍候”,避免用户误操作导致状态异常 - 下载
.wgt时要用uni.downloadFile,别用uni.request,否则二进制流可能被自动转成字符串导致损坏
最易忽略的一点:后端接口返回的 filepath 必须是 HTTPS 地址,HTTP 在 iOS 12+ 和 Android 9+ 默认被拦截;另外,APK 下载链接需带正确 MIME 头(Content-Type: application/vnd.android.package-archive),否则部分安卓机型无法识别安装意图。











