540 行
17 KiB
Markdown
540 行
17 KiB
Markdown
|
|
# XuqmGroup SDK 设计规范
|
|||
|
|
|
|||
|
|
> 版本:v2.0
|
|||
|
|
> 生效范围:**全平台** — Android、iOS、React Native、Flutter、HarmonyOS、微信小程序、Vue3、Java / Python / Go 服务端 SDK
|
|||
|
|
> 状态:需求确认,待各平台落地实现
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 一、设计原则
|
|||
|
|
|
|||
|
|
1. **App 零感知初始化**:配置文件方式下,App 无需写任何初始化代码。
|
|||
|
|
2. **一次认证,全局生效**:`setUserInfo()` 一次调用,所有子 SDK(Push、IM、License 等)自动同步状态。
|
|||
|
|
3. **失败即失败**:初始化失败、认证失败均抛出错误,不静默降级。
|
|||
|
|
4. **服务按需激活**:哪些服务(IM、推送、License 等)由租户平台配置决定,SDK 根据返回配置自动激活对应能力,App 层无需判断。
|
|||
|
|
5. **子 SDK 独立性**:各子 SDK 之间通过 `common` 共享上下文(appKey、baseUrl、userId 等),不互相硬依赖。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 二、XuqmSDK(核心 — @xuqm/rn-common)
|
|||
|
|
|
|||
|
|
### 2.1 初始化方式(仅两种)
|
|||
|
|
|
|||
|
|
#### 方式 A:配置文件自动初始化(推荐)
|
|||
|
|
|
|||
|
|
App 在构建阶段将加密配置文件(`.xuqmconfig`)放置到指定路径,SDK 在模块加载时自动读取并初始化。App 无需调用任何初始化代码。
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
配置文件路径(RN):src/assets/xuqm/config.xuqmconfig
|
|||
|
|
配置文件格式:见 docs/配置文件规范.md
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
配置文件内容(加密前)包含:
|
|||
|
|
- `appKey`:应用标识
|
|||
|
|
- `platformUrl`:平台地址(从哪里拉取服务配置)
|
|||
|
|
|
|||
|
|
SDK 读取配置文件后,自动调用 **方式 B** 完成完整初始化(拉取远程服务配置)。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### 方式 B:手动初始化
|
|||
|
|
|
|||
|
|
App 主动调用,适用于无法提前写入配置文件或需要动态切换环境的场景。
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
await XuqmSDK.initialize({
|
|||
|
|
appKey: 'your-app-key',
|
|||
|
|
platformUrl: 'https://www.51szyx.com', // 平台地址,必填
|
|||
|
|
debug: __DEV__,
|
|||
|
|
})
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**行为**:
|
|||
|
|
1. 请求 `{platformUrl}/api/sdk/config?appKey={appKey}`
|
|||
|
|
2. 平台根据 appKey 和租户服务开通情况,返回该 App 专属的服务配置:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"apiUrl": "...", // 通用 API 地址
|
|||
|
|
"imWsUrl": "...", // IM WebSocket 地址(未开通则为 null)
|
|||
|
|
"fileServiceUrl": "...", // 文件服务地址
|
|||
|
|
"pushEnabled": true, // 是否开通推送服务
|
|||
|
|
"licenseEnabled": false, // 是否开通 License 服务
|
|||
|
|
"imEnabled": true // 是否开通 IM 服务
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
3. SDK 将服务配置保存,供所有子 SDK 使用。
|
|||
|
|
4. **失败时直接抛出错误**,不降级,不回退到默认地址。调用方必须处理异常。
|
|||
|
|
|
|||
|
|
**签名**:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
interface XuqmInitOptions {
|
|||
|
|
appKey: string
|
|||
|
|
platformUrl: string // 平台地址,必填
|
|||
|
|
debug?: boolean
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
XuqmSDK.initialize(options: XuqmInitOptions): Promise<void>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
#### 已移除(不再提供)
|
|||
|
|
|
|||
|
|
| 方法 | 移除原因 |
|
|||
|
|
|------|---------|
|
|||
|
|
| `XuqmSDK.initializeFromLicense(file, options?)` | License 是独立小服务,不承担 SDK 初始化职责 |
|
|||
|
|
| `XuqmSDK.init(options): void` | 同步 init 不拉取服务配置,行为不完整;用方式 A 或方式 B 替代 |
|
|||
|
|
| `XuqmSDK.initWithConfigFile(encrypted)` | 由自动初始化机制内部调用,不对外暴露 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 2.2 用户认证:setUserInfo(核心枢纽)
|
|||
|
|
|
|||
|
|
`setUserInfo` 是所有子 SDK 用户状态同步的入口。**登录成功后调用一次,所有子 SDK 自动激活**。
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
interface XuqmUserInfo {
|
|||
|
|
userId: string // 必填
|
|||
|
|
userSig?: string // IM 服务必填;租户未开通 IM 时可不传
|
|||
|
|
name?: string
|
|||
|
|
phone?: string
|
|||
|
|
avatar?: string
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
XuqmSDK.setUserInfo(info: XuqmUserInfo): void
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**调用后的内部行为(自动、静默)**:
|
|||
|
|
|
|||
|
|
| 子 SDK | 触发动作 |
|
|||
|
|
|--------|---------|
|
|||
|
|
| PushSDK | 自动执行设备注册流程(见第三节) |
|
|||
|
|
| ImSDK | 若 `userSig` 存在且平台开通了 IM,自动登录 IM 服务 |
|
|||
|
|
| LicenseSDK | 更新用户上下文,供 License 验证使用 |
|
|||
|
|
| UpdateSDK | 更新 userId,用于租户平台配置的灰度/定向更新 |
|
|||
|
|
|
|||
|
|
**登出时**:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
XuqmSDK.setUserInfo(null)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
触发所有子 SDK 登出:PushSDK 解绑 token,ImSDK 断开连接,清除所有用户上下文。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 2.3 其他方法(保留)
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
XuqmSDK.getUserId(): string | null
|
|||
|
|
XuqmSDK.getUserInfo(): XuqmUserInfo | null
|
|||
|
|
XuqmSDK.awaitInitialization(): Promise<void> // 等待初始化完成
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 三、PushSDK(推送 — @xuqm/rn-push)
|
|||
|
|
|
|||
|
|
### 3.1 初始化方式
|
|||
|
|
|
|||
|
|
**无需显式初始化**。当 `XuqmSDK.setUserInfo(info)` 被调用时,PushSDK 自动执行以下流程:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
setUserInfo(info)
|
|||
|
|
└─ PushSDK 内部触发:
|
|||
|
|
1. detectPushVendor() — 自动检测当前设备厂商(华为/小米/OPPO/vivo/荣耀/FCM/APNs)
|
|||
|
|
2. fetchVendorConfig(vendor) — 从平台获取该厂商推送配置(AppID、Secret 等)
|
|||
|
|
3. registerWithVendorSDK() — 调用厂商 SDK 完成设备注册
|
|||
|
|
4. onTokenReceived(token) — 收到 token 后自动上报绑定到平台
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
App 层无需关心设备厂商类型,也无需手动调用注册流程。
|
|||
|
|
|
|||
|
|
### 3.2 App 层可调用的 API
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
// 设置离线推送开关
|
|||
|
|
PushSDK.setOfflinePushEnabled(enabled: boolean): Promise<void>
|
|||
|
|
|
|||
|
|
// 设置免打扰时间段(24小时制)
|
|||
|
|
PushSDK.setQuietHours(start: string, end: string): Promise<void>
|
|||
|
|
// 示例:PushSDK.setQuietHours('22:00', '08:00')
|
|||
|
|
|
|||
|
|
// 清除免打扰设置
|
|||
|
|
PushSDK.clearQuietHours(): Promise<void>
|
|||
|
|
|
|||
|
|
// 登出(通常不需要手动调用,setUserInfo(null) 会自动触发)
|
|||
|
|
PushSDK.logout(): Promise<void>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3.3 已移除
|
|||
|
|
|
|||
|
|
| 方法 | 移除原因 |
|
|||
|
|
|------|---------|
|
|||
|
|
| `PushSDK.initialize(userId?)` | 由 `setUserInfo` 触发,不对外暴露 |
|
|||
|
|
| `PushSDK.requestNativeRegistration()` | 内部流程,不对外暴露 |
|
|||
|
|
| `PushSDK.registerToken(userId, token, vendor?)` | 内部流程,不对外暴露 |
|
|||
|
|
| `PushSDK.onPushToken(callback)` | 内部流程,不对外暴露 |
|
|||
|
|
| `PushSDK.unregisterToken(userId)` | 由 `setUserInfo(null)` 触发 |
|
|||
|
|
| `PushSDK.setPendingToken / getPendingToken` | 内部状态,不对外暴露 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 四、ImSDK(即时通讯 — @xuqm/rn-im)
|
|||
|
|
|
|||
|
|
### 4.1 初始化与登录
|
|||
|
|
|
|||
|
|
**无需显式初始化**。依赖 `XuqmSDK.initialize()` 完成服务配置获取后即可工作。
|
|||
|
|
|
|||
|
|
**登录**:通过 `XuqmSDK.setUserInfo({ userId, userSig })` 自动触发,不需要 App 直接调用 `ImSDK.login()`。
|
|||
|
|
|
|||
|
|
**userSig 获取方式**:
|
|||
|
|
- App 登录成功后,由 App 服务端根据业务逻辑生成并返回
|
|||
|
|
- userSig 通常有时效性(建议 7 天),App 应在登录响应中一并返回
|
|||
|
|
- App 在调用 `setUserInfo` 时传入,无需关心 IM 内部实现
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
// App 登录后的标准流程
|
|||
|
|
const loginResult = await api.login(phone, code)
|
|||
|
|
XuqmSDK.setUserInfo({
|
|||
|
|
userId: loginResult.userId,
|
|||
|
|
userSig: loginResult.userSig, // 服务端随登录一并返回
|
|||
|
|
name: loginResult.name,
|
|||
|
|
phone: loginResult.phone,
|
|||
|
|
})
|
|||
|
|
// → PushSDK 自动注册
|
|||
|
|
// → ImSDK 自动登录(若租户开通了 IM)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.2 userSig 刷新
|
|||
|
|
|
|||
|
|
当 userSig 过期或需要主动刷新时:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
const newSig = await api.refreshUserSig()
|
|||
|
|
ImSDK.refreshToken(newSig): Promise<void>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
或通过重新调用 `setUserInfo` 携带新 userSig。
|
|||
|
|
|
|||
|
|
### 4.3 IM 与 Push 共用用户上下文
|
|||
|
|
|
|||
|
|
Push 和 IM 共享 `XuqmSDK` 的用户上下文(userId),两者通过 `setUserInfo` 统一管理:
|
|||
|
|
- 同一个 userId 用于 Push 设备绑定和 IM 登录
|
|||
|
|
- `setUserInfo(null)` 统一触发 Push 解绑和 IM 断连
|
|||
|
|
|
|||
|
|
### 4.4 可用方法
|
|||
|
|
|
|||
|
|
ImSDK 的具体 API 方法(消息收发、群组、好友等)保持现有设计不变,见 `docs/SDK-API参考.md` 第 5 节。
|
|||
|
|
|
|||
|
|
仅以下方法调整:
|
|||
|
|
|
|||
|
|
| 方法 | 变化 |
|
|||
|
|
|------|------|
|
|||
|
|
| `ImSDK.login(userId, userSig)` | 保留,但通常不需要 App 直接调用(由 setUserInfo 触发) |
|
|||
|
|
| `ImSDK.refreshToken(userSig)` | **新增**,用于 userSig 过期刷新 |
|
|||
|
|
| `ImSDK.disconnect()` | 保留,通常不需要直接调用(setUserInfo(null) 触发) |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 五、UpdateSDK(更新 — @xuqm/rn-update)
|
|||
|
|
|
|||
|
|
### 5.1 插件注册
|
|||
|
|
|
|||
|
|
#### 批量注册(推荐)
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
UpdateSDK.registerPlugins([
|
|||
|
|
{ moduleId: 'buz1' },
|
|||
|
|
{ moduleId: 'buz2' },
|
|||
|
|
{ moduleId: 'buz3' },
|
|||
|
|
])
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**版本号由 SDK 自动获取**,不需要 App 传入:
|
|||
|
|
- SDK 从本地 manifest 文件读取当前已安装的插件版本
|
|||
|
|
- 如果 manifest 中无记录(首次安装),视为版本 `0.0.0`
|
|||
|
|
|
|||
|
|
#### 单个注册(仍支持,向后兼容)
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
UpdateSDK.registerPlugin({ moduleId: 'buz1' })
|
|||
|
|
// 注意:不再接受 version 字段
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**类型定义变更**:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
// 旧
|
|||
|
|
interface PluginMeta {
|
|||
|
|
moduleId: string
|
|||
|
|
version: string // ← 移除
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 新
|
|||
|
|
interface PluginRegistration {
|
|||
|
|
moduleId: string
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.2 App 整包更新
|
|||
|
|
|
|||
|
|
#### 检查更新
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
const info = await UpdateSDK.checkAppUpdate(bypassIgnore?: boolean): Promise<AppUpdateInfo>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Android APK 直接下载安装(新增)
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
// 下载 APK 并在完成后调起系统安装器
|
|||
|
|
await UpdateSDK.downloadAndInstallApk(
|
|||
|
|
downloadUrl: string,
|
|||
|
|
options?: {
|
|||
|
|
onProgress?: (progress: number) => void // 0~1
|
|||
|
|
sha256?: string // 校验值,有则验证
|
|||
|
|
}
|
|||
|
|
): Promise<void>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**完整整包更新流程示例**:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
const info = await UpdateSDK.checkAppUpdate()
|
|||
|
|
if (!info.needsUpdate) return
|
|||
|
|
|
|||
|
|
if (Platform.OS === 'android' && info.downloadUrl) {
|
|||
|
|
// Android:直接下载安装
|
|||
|
|
await UpdateSDK.downloadAndInstallApk(info.downloadUrl, {
|
|||
|
|
onProgress: (p) => setProgress(p),
|
|||
|
|
sha256: info.apkHash ?? undefined,
|
|||
|
|
})
|
|||
|
|
} else {
|
|||
|
|
// iOS / Android 商店跳转
|
|||
|
|
await UpdateSDK.openStore(info.appStoreUrl, info.marketUrl)
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.3 插件(Bundle)热更新
|
|||
|
|
|
|||
|
|
**两个方法,SDK 自动完成所有步骤**:
|
|||
|
|
|
|||
|
|
#### 方法 1:检查更新信息
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
const info = await UpdateSDK.checkPluginUpdate(moduleId: string): Promise<PluginUpdateInfo>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
App 层拿到 `info` 后可自行决定:弹窗提示用户、静默后台更新或忽略。
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
interface PluginUpdateInfo {
|
|||
|
|
needsUpdate: boolean
|
|||
|
|
latestVersion: string
|
|||
|
|
currentVersion: string // 新增:SDK 自动填入
|
|||
|
|
changeLog?: string
|
|||
|
|
forceUpdate?: boolean // 新增:强制更新标识
|
|||
|
|
minCommonVersion?: string // 要求的最低 common bundle 版本
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 方法 2:执行更新
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
await UpdateSDK.updatePlugin(
|
|||
|
|
moduleId: string,
|
|||
|
|
options?: {
|
|||
|
|
onProgress?: (progress: number) => void
|
|||
|
|
silent?: boolean // true = 静默更新(不重载,下次启动生效)
|
|||
|
|
}
|
|||
|
|
): Promise<void>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**SDK 内部自动完成**:
|
|||
|
|
1. 调用 `checkPluginUpdate()` 确认有更新
|
|||
|
|
2. 下载 bundle(带进度回调)
|
|||
|
|
3. 写入文件系统(`rn-bundles/<moduleId>.<platform>.bundle`)
|
|||
|
|
4. 若 `silent = false`(默认),触发宿主重载当前插件
|
|||
|
|
|
|||
|
|
**一步完成(静默后台更新)**:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
// 启动时后台静默检查并缓存,下次进入插件生效
|
|||
|
|
await UpdateSDK.updatePlugin('buz1', { silent: true })
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**带确认弹窗的前台更新**:
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
const info = await UpdateSDK.checkPluginUpdate('buz1')
|
|||
|
|
if (info.needsUpdate) {
|
|||
|
|
const confirmed = info.forceUpdate || (await showConfirm(`发现新版本 ${info.latestVersion},是否更新?`))
|
|||
|
|
if (confirmed) {
|
|||
|
|
await UpdateSDK.updatePlugin('buz1', {
|
|||
|
|
onProgress: (p) => setProgress(p),
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.4 已移除 / 废弃
|
|||
|
|
|
|||
|
|
| 方法 | 替代 |
|
|||
|
|
|------|------|
|
|||
|
|
| `UpdateSDK.checkAndCachePlugin(moduleId)` | `UpdateSDK.updatePlugin(moduleId, { silent: true })` |
|
|||
|
|
| `UpdateSDK.downloadPluginBundle(url)` | 内部实现,不对外暴露 |
|
|||
|
|
| `UpdateSDK.cachePluginBundle(...)` | 内部实现,不对外暴露 |
|
|||
|
|
| `UpdateSDK.getCachedPluginBundle(moduleId)` | 内部实现,不对外暴露 |
|
|||
|
|
| `PluginMeta.version`(注册时传 version)| SDK 自动从 manifest 读取 |
|
|||
|
|
|
|||
|
|
### 5.5 用户定向更新
|
|||
|
|
|
|||
|
|
灰度/定向更新的用户白名单在**租户平台**配置,SDK 无需感知。UpdateSDK 在检查更新时会自动携带当前 `userId`(来自 `XuqmSDK.getUserId()`),由服务端决定是否返回 `needsUpdate: true`。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 六、LicenseSDK(License 服务 — @xuqm/rn-license)
|
|||
|
|
|
|||
|
|
### 6.1 定位
|
|||
|
|
|
|||
|
|
License 是**独立小服务**,大多数租户不会开通。它:
|
|||
|
|
- 不承担 SDK 初始化职责
|
|||
|
|
- 不向其他 SDK 提供基础能力
|
|||
|
|
- 与 IM / Push / Update 等没有依赖关系
|
|||
|
|
- 使用 `XuqmSDK` 的 `apiUrl`、`appKey`、`userId` 等公共上下文
|
|||
|
|
|
|||
|
|
### 6.2 初始化方式
|
|||
|
|
|
|||
|
|
**无需独立初始化**。LicenseSDK 在调用任何方法前会内部调用 `XuqmSDK.awaitInitialization()`,等待核心 SDK 就绪后直接使用其配置。
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
// App 只需调用 XuqmSDK.initialize(),LicenseSDK 无需额外操作
|
|||
|
|
await XuqmSDK.initialize({ appKey, platformUrl })
|
|||
|
|
// ...用户登录...
|
|||
|
|
XuqmSDK.setUserInfo({ userId, ... })
|
|||
|
|
|
|||
|
|
// 然后即可直接调用 LicenseSDK 方法
|
|||
|
|
const license = await LicenseSDK.validateLicense(licenseId)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 6.3 已移除
|
|||
|
|
|
|||
|
|
| 方法 | 移除原因 |
|
|||
|
|
|------|---------|
|
|||
|
|
| `LicenseSDK.initialize(...)` | 依赖 XuqmSDK,无需独立初始化 |
|
|||
|
|
| `XuqmSDK.initializeFromLicense(file)` | License 文件不承担 SDK 初始化职责 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 七、SDK 整体架构图
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
App
|
|||
|
|
├── XuqmSDK.initialize(appKey, platformUrl)
|
|||
|
|
│ └─ 拉取平台配置 ──────────────────────────────┐
|
|||
|
|
│ │ 返回各服务 URL 和开通状态
|
|||
|
|
│ ← apiUrl / imWsUrl / fileServiceUrl ──────────┘
|
|||
|
|
│
|
|||
|
|
├── XuqmSDK.setUserInfo({ userId, userSig?, ... })
|
|||
|
|
│ ├─ PushSDK ──── 自动检测厂商 → 获取厂商配置 → 注册设备 → 上报 token
|
|||
|
|
│ ├─ ImSDK ─────── 自动登录(若 userSig 存在且 IM 已开通)
|
|||
|
|
│ ├─ UpdateSDK ─── 更新 userId(用于定向更新)
|
|||
|
|
│ └─ LicenseSDK ── 更新用户上下文
|
|||
|
|
│
|
|||
|
|
└── XuqmSDK.setUserInfo(null)
|
|||
|
|
├─ PushSDK ──── 解绑 token
|
|||
|
|
└─ ImSDK ─────── 断开连接
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 八、各子 SDK 依赖关系
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
@xuqm/rn-common ← XuqmSDK 核心、HTTP 客户端、设备信息、公共上下文
|
|||
|
|
▲
|
|||
|
|
│ 依赖(通过 awaitInitialization + getConfig + getUserId 等)
|
|||
|
|
├── @xuqm/rn-push
|
|||
|
|
├── @xuqm/rn-im
|
|||
|
|
├── @xuqm/rn-update
|
|||
|
|
├── @xuqm/rn-xwebview
|
|||
|
|
└── @xuqm/rn-license
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
子 SDK 之间**不互相依赖**,均通过 `@xuqm/rn-common` 共享配置和用户上下文。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 九、初始化完整流程参考
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
// 1. 初始化(通常在 App 入口,配置文件模式下可省略)
|
|||
|
|
await XuqmSDK.initialize({
|
|||
|
|
appKey: 'your-app-key',
|
|||
|
|
platformUrl: 'https://www.51szyx.com',
|
|||
|
|
debug: __DEV__,
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
// 2. 业务登录(App 自有登录逻辑)
|
|||
|
|
const result = await api.login(phone, verifyCode)
|
|||
|
|
|
|||
|
|
// 3. 一次调用,全局生效
|
|||
|
|
XuqmSDK.setUserInfo({
|
|||
|
|
userId: result.userId,
|
|||
|
|
userSig: result.userSig, // 服务端随登录返回
|
|||
|
|
name: result.name,
|
|||
|
|
phone: result.phone,
|
|||
|
|
})
|
|||
|
|
// → PushSDK 自动完成设备注册
|
|||
|
|
// → ImSDK 自动完成 IM 登录(若开通)
|
|||
|
|
|
|||
|
|
// 4. 插件热更新(后台静默,启动时调用一次)
|
|||
|
|
await UpdateSDK.registerPlugins([
|
|||
|
|
{ moduleId: 'buz1' },
|
|||
|
|
{ moduleId: 'buz2' },
|
|||
|
|
])
|
|||
|
|
await Promise.all([
|
|||
|
|
UpdateSDK.updatePlugin('buz1', { silent: true }),
|
|||
|
|
UpdateSDK.updatePlugin('buz2', { silent: true }),
|
|||
|
|
])
|
|||
|
|
|
|||
|
|
// 5. 登出
|
|||
|
|
XuqmSDK.setUserInfo(null)
|
|||
|
|
// → PushSDK 解绑,ImSDK 断连,userId 清除
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 十、跨平台实现要求
|
|||
|
|
|
|||
|
|
本文档中所有设计均为**跨平台通用需求**,适用于:
|
|||
|
|
|
|||
|
|
| 平台 | SDK 包 |
|
|||
|
|
|------|--------|
|
|||
|
|
| Android(原生) | `xuqm-android-sdk` |
|
|||
|
|
| iOS(原生) | `XuqmSDK.framework` |
|
|||
|
|
| React Native | `@xuqm/rn-*` |
|
|||
|
|
| Flutter | `xuqm_flutter_sdk` |
|
|||
|
|
| HarmonyOS | `xuqm_harmony_sdk` |
|
|||
|
|
| 微信小程序 | `xuqm-miniprogram-sdk` |
|
|||
|
|
| Vue3(H5) | `@xuqm/vue-sdk` |
|
|||
|
|
| Java 服务端 | `xuqm-java-sdk` |
|
|||
|
|
| Python 服务端 | `xuqm-python-sdk` |
|
|||
|
|
| Go 服务端 | `xuqm-go-sdk` |
|
|||
|
|
|
|||
|
|
各平台在实现时应在 API 签名和行为上保持一致;平台差异(如服务端 SDK 无 Push/IM 客户端能力)通过能力矩阵文档说明。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 十一、待讨论 / 待决策事项
|
|||
|
|
|
|||
|
|
| 事项 | 当前状态 | 说明 |
|
|||
|
|
|------|---------|------|
|
|||
|
|
| userSig 过期自动刷新 | 待设计 | 是否由 SDK 内部定时刷新,还是 App 层感知过期后手动调用 `refreshToken`? |
|
|||
|
|
| IM 未开通时 userSig 传入是否报警 | 待决策 | 建议在 debug 模式下打印警告 |
|
|||
|
|
| PushSDK 厂商配置获取失败降级策略 | 待决策 | 获取厂商配置失败时是否还尝试使用上次缓存配置? |
|
|||
|
|
| 配置文件格式版本向上兼容 | 进行中 | 见 `docs/配置文件规范.md` |
|
|||
|
|
| 服务端 SDK(Java/Go/Python)的 setUserInfo 等效方法 | 待设计 | 服务端无设备/Push 概念,需要单独定义 |
|