XuqmGroup-Web/docs-site/docs/rn/update.md

234 行
5.5 KiB
Markdown

# 版本与插件更新
`@xuqm/rn-update` 提供两类能力:
- Android 整包检查、下载、安装和应用商店跳转。
- 可选的 RN 插件检查、安装和启动。
SDK 返回更新信息和当前网络状态,是否弹窗、是否允许使用移动网络以及何时开始下载由宿主
决定。
## 整包更新
### 检查
```ts
import { UpdateSDK } from '@xuqm/rn-update'
const result = await UpdateSDK.checkAppUpdate()
switch (result.status) {
case 'UPDATE_AVAILABLE':
showUpdateDialog(result.update, result.network)
break
case 'LOGIN_REQUIRED':
case 'SERVICE_DISABLED':
case 'NO_UPDATE':
// 正常跳过,不阻断应用
break
case 'FAILED':
// 记录一次非阻断诊断
console.warn(result.errorCode, result.message)
break
}
```
检查状态:
| 状态 | 宿主建议 |
| --- | --- |
| `UPDATE_AVAILABLE` | 根据 `forceUpdate` 展示宿主自己的更新弹窗 |
| `NO_UPDATE` | 继续启动 |
| `LOGIN_REQUIRED` | 未登录时跳过,登录后可再次检查 |
| `SERVICE_DISABLED` | 服务未启用,继续运行 |
| `FAILED` | 记录诊断,不阻断宿主 |
`result.network` 包含连接类型、是否已连接和是否按流量计费。租户平台不替宿主配置网络
策略。
### 下载并安装
用户确认后调用:
```ts
await UpdateSDK.downloadAndInstallApp(result.update!, {
destination: 'SDK_PRIVATE',
onProgress(progress) {
setProgress(progress.percent)
},
})
```
需要把安装包保留在系统 Downloads
```ts
await UpdateSDK.downloadAndInstallApp(result.update!, {
destination: 'PUBLIC_DOWNLOADS',
})
```
下载失败或应用退出后不会在下次启动时自动继续。
### 只下载、稍后安装
```ts
import { NativeAppUpdate, UpdateSDK } from '@xuqm/rn-update'
const downloaded = await UpdateSDK.downloadApk(result.update!, {
destination: 'SDK_PRIVATE',
})
console.log(downloaded.localPath)
await NativeAppUpdate.installDownloaded({
versionCode: result.update!.versionCode!,
sha256: result.update!.sha256,
})
```
取消当前下载:
```ts
await NativeAppUpdate.cancel()
```
如果系统禁止安装未知来源应用:
```ts
await NativeAppUpdate.openInstallPermissionSettings()
```
### 跳转应用商店
宿主不传商店地址,只传检查接口返回的更新对象:
```ts
const opened = await UpdateSDK.openStore(result.update!)
```
Android 会优先打开当前设备对应的应用商店,不可用时使用平台提供的通用下载页。iOS 或
HarmonyOS 没有配置商店地址时返回 `false`,宿主应提示当前无法提供下载服务。
### 忽略可选版本
```ts
await UpdateSDK.ignoreAppVersion(result.update!.versionCode!)
const ignoredVersion = await UpdateSDK.getIgnoredAppVersion()
await UpdateSDK.clearIgnoredAppVersion()
```
强制更新不能被忽略。
## 不启用插件化
普通项目可以只使用上述整包更新 API,不创建 `common/app/buz` 模块,也不需要接入插件
运行时。后续需要插件化时再执行初始化命令即可。
## 启用插件化
在项目根目录执行交互式初始化:
```bash
pnpm exec xuqm-rn init
pnpm run xuqm:doctor
```
初始化工具会创建 `xuqm.modules.json`、补充必要脚本并提示宿主完成最少原生配置。不要
手工复制其他项目的模块表。
Metro 使用:
```js
const { getDefaultConfig } = require('@react-native/metro-config')
const { withXuqmModuleConfig } = require('@xuqm/rn-update/metro')
module.exports = withXuqmModuleConfig(getDefaultConfig(__dirname))
```
Android 宿主应用一次构建脚本:
```groovy
apply from: file("../../node_modules/@xuqm/rn-update/android/xuqm-bundles.gradle")
```
### 注册宿主运行时
```ts
import { XuqmRuntime } from '@xuqm/rn-update'
XuqmRuntime.configure({
plugins: pluginRegistrations,
context: {
navigate(route, params) {
navigationRef.navigate(route, params)
},
emit(event, payload) {
hostEvents.emit(event, payload)
},
getHostState() {
return appStore.getState()
},
},
async loadBundle(_moduleId, bundlePath) {
await bundleLoader.load(bundlePath)
},
})
```
模块入口注册:
```ts
import { definePlugin } from '@xuqm/rn-update'
definePlugin({
moduleId: 'orders',
activate(context) {
context.navigate('OrdersHome')
},
})
```
### 检查与安装插件
自动完成检查和安装:
```ts
const plan = await UpdateSDK.checkAndInstallPlugin('orders', {
onProgress(moduleId, progress) {
console.log(moduleId, progress.percent)
},
})
await XuqmRuntime.activate('orders', {
reloadBundle: plan !== null,
})
```
宿主需要先展示确认弹窗时:
```ts
const plan = await UpdateSDK.checkPluginRelease('orders')
if (plan && (await showPluginUpdateDialog(plan))) {
await UpdateSDK.installPluginRelease(plan)
}
```
只检查不会下载或修改本地状态。插件检查失败时,宿主应继续打开已有的本地健康版本。
## 启动策略
- 启动时先检查整包更新。
- 不需要整包更新时,再检查 App 插件。
- 业务插件在进入前分别检查。
- Debug 默认不自动检查;开发页可以显式使用 `UpdateSDK.developer` 下的测试入口。
- 更新 SDK 不绘制业务弹窗,所有提示和确认交互由宿主实现。
## 打包与发布
初始化生成的脚本支持 Debug、Release、插件构建和上传。发布令牌只通过 CI 环境变量
`XUQM_API_TOKEN` 注入,不写入项目配置、源码或产物。
SDK 自身制品发布与应用/插件发布是不同操作。应用开发者不需要发布 SDK,也不得把 SDK
发布凭据加入宿主工程。