2026-04-24 15:35:24 +08:00
|
|
|
|
# React Native SDK 概览
|
|
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
**包名**:`@xuqm/rn-sdk` · **版本**:0.3.0 · **支持**:React Native 0.73+
|
2026-04-24 15:35:24 +08:00
|
|
|
|
|
|
|
|
|
|
## 功能模块
|
|
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
| 包 | 功能 |
|
|
|
|
|
|
|----|------|
|
|
|
|
|
|
| `@xuqm/rn-common` | 初始化、网络、设备信息(必须) |
|
|
|
|
|
|
| `@xuqm/rn-im` | 单聊、群聊、消息收发、本地 DB |
|
|
|
|
|
|
| `@xuqm/rn-push` | 推送设备 Token 上报 |
|
|
|
|
|
|
| `@xuqm/rn-update` | App 版本检查、RN Bundle 热更新 |
|
|
|
|
|
|
| `@xuqm/rn-sdk` | 以上所有模块的 meta 包(推荐直接使用) |
|
2026-04-24 15:35:24 +08:00
|
|
|
|
|
|
|
|
|
|
## 安装
|
|
|
|
|
|
|
|
|
|
|
|
在项目根目录创建 `.npmrc`:
|
|
|
|
|
|
|
|
|
|
|
|
```
|
2026-04-27 11:58:17 +08:00
|
|
|
|
@xuqm:registry=https://nexus.xuqinmin.com/repository/npm/
|
2026-04-24 15:35:24 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
安装 meta 包(包含全部功能):
|
2026-04-24 15:35:24 +08:00
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
yarn add @xuqm/rn-sdk
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
或按需安装(减小包体积):
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
yarn add @xuqm/rn-common @xuqm/rn-im
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-04-24 15:35:24 +08:00
|
|
|
|
## 快速接入
|
|
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
### 1. 初始化(推荐异步方式)
|
2026-04-24 15:35:24 +08:00
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
import { XuqmSDK } from '@xuqm/rn-sdk'
|
|
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
// 推荐:从租户平台拉取完整配置
|
|
|
|
|
|
await XuqmSDK.initialize({
|
|
|
|
|
|
appId: 'your_app_id',
|
|
|
|
|
|
serverUrl: 'https://your-server.com',
|
|
|
|
|
|
debug: __DEV__,
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 兼容:同步初始化,不发网络请求,根据 serverUrl 推导 URL
|
2026-04-24 15:35:24 +08:00
|
|
|
|
XuqmSDK.init({
|
2026-04-27 11:58:17 +08:00
|
|
|
|
appId: 'your_app_id',
|
|
|
|
|
|
serverUrl: 'https://your-server.com',
|
2026-04-24 15:35:24 +08:00
|
|
|
|
})
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
> `initialize` 自动从 `GET /api/sdk/config?appId=` 获取 imWsUrl、fileServiceUrl 等配置,并在网络失败时 fallback 到 serverUrl 推导值。
|
|
|
|
|
|
|
2026-04-24 15:35:24 +08:00
|
|
|
|
### 2. IM 登录
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
import { ImSDK } from '@xuqm/rn-sdk'
|
|
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
// 使用 IM token(由你的业务服务端签发)
|
|
|
|
|
|
await ImSDK.loginWithToken('user_001', 'im_token_from_server', 'xuqm_im')
|
|
|
|
|
|
|
|
|
|
|
|
// 直接登录(适用于 im-service 直接认证场景)
|
|
|
|
|
|
await ImSDK.login('user_001', '张三', 'https://cdn.example.com/avatar.jpg', 'xuqm_im')
|
2026-04-24 15:35:24 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
### 3. 监听消息与连接状态
|
2026-04-24 15:35:24 +08:00
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
import type { ImEventListener } from '@xuqm/rn-sdk'
|
|
|
|
|
|
|
|
|
|
|
|
const listener: ImEventListener = {
|
2026-04-27 11:58:17 +08:00
|
|
|
|
onConnected() { console.log('WS 已连接') },
|
|
|
|
|
|
onDisconnected(reason) { console.log('WS 断开:', reason) },
|
|
|
|
|
|
onMessage(msg) { /* 收到单聊消息 */ },
|
|
|
|
|
|
onGroupMessage(msg) { /* 收到群聊消息 */ },
|
2026-04-24 15:35:24 +08:00
|
|
|
|
onError(err) { console.error(err) },
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ImSDK.addListener(listener)
|
2026-04-27 11:58:17 +08:00
|
|
|
|
return () => ImSDK.removeListener(listener)
|
2026-04-24 15:35:24 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 4. 发送消息
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
2026-04-27 11:58:17 +08:00
|
|
|
|
// 文本消息
|
|
|
|
|
|
const msg = await ImSDK.sendMessage('user_002', 'SINGLE', 'TEXT', 'Hello!')
|
|
|
|
|
|
|
|
|
|
|
|
// 图片(SDK 自动上传到 file-service)
|
|
|
|
|
|
const msg = await ImSDK.sendImageMessage('user_002', 'SINGLE', localUri, width, height)
|
2026-04-24 15:35:24 +08:00
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
// 视频
|
|
|
|
|
|
const msg = await ImSDK.sendVideoMessage('user_002', 'SINGLE', localUri, thumbnailUri, durationSeconds)
|
|
|
|
|
|
|
|
|
|
|
|
// 语音
|
|
|
|
|
|
const msg = await ImSDK.sendAudioMessage('user_002', 'SINGLE', localUri, durationSeconds)
|
|
|
|
|
|
|
|
|
|
|
|
// 文件
|
|
|
|
|
|
const msg = await ImSDK.sendFileMessage('user_002', 'SINGLE', localUri, 'report.pdf', fileSize)
|
2026-04-24 15:35:24 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
### 5. 拉取历史消息
|
2026-04-24 15:35:24 +08:00
|
|
|
|
|
|
|
|
|
|
```ts
|
2026-04-27 11:58:17 +08:00
|
|
|
|
// 单聊历史(先读本地 DB,再回源服务端)
|
|
|
|
|
|
const history = await ImSDK.fetchHistory('user_002', 0, 30)
|
|
|
|
|
|
|
|
|
|
|
|
// 群聊历史
|
|
|
|
|
|
const gHistory = await ImSDK.fetchGroupHistory(groupId, 0, 30)
|
2026-04-24 15:35:24 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
### 6. 会话列表(响应式)
|
2026-04-24 15:35:24 +08:00
|
|
|
|
|
|
|
|
|
|
```ts
|
2026-04-27 11:58:17 +08:00
|
|
|
|
// 订阅本地 DB 变更,新消息/已读/静音/置顶都会触发回调
|
|
|
|
|
|
const unsub = ImSDK.subscribeConversations((convs) => {
|
|
|
|
|
|
setConversations(convs)
|
|
|
|
|
|
})
|
|
|
|
|
|
return unsub // 组件卸载时调用
|
|
|
|
|
|
|
|
|
|
|
|
// 标记已读
|
|
|
|
|
|
await ImSDK.markRead('user_002')
|
2026-04-24 15:35:24 +08:00
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
// 置顶/静音
|
|
|
|
|
|
await ImSDK.setConversationPinned('user_002', 'SINGLE', true)
|
|
|
|
|
|
await ImSDK.setConversationMuted('user_002', 'SINGLE', true)
|
2026-04-24 15:35:24 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 7. 群聊
|
|
|
|
|
|
|
|
|
|
|
|
```ts
|
2026-04-27 11:58:17 +08:00
|
|
|
|
// 创建群
|
|
|
|
|
|
const group = await ImSDK.createGroup('讨论组', ['user_001', 'user_002'])
|
2026-04-24 15:35:24 +08:00
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
// 订阅群消息 WebSocket topic
|
2026-04-24 15:35:24 +08:00
|
|
|
|
ImSDK.subscribeGroup(group.id)
|
|
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
// 群消息撤回
|
|
|
|
|
|
await ImSDK.revokeMessage(messageId)
|
2026-04-24 15:35:24 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
### 8. 好友管理
|
2026-04-24 15:35:24 +08:00
|
|
|
|
|
|
|
|
|
|
```ts
|
2026-04-27 11:58:17 +08:00
|
|
|
|
await ImSDK.addFriend('user_002')
|
|
|
|
|
|
await ImSDK.removeFriend('user_002')
|
|
|
|
|
|
const friends = await ImSDK.listFriends()
|
2026-04-24 15:35:24 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
### 9. 消息搜索
|
2026-04-24 15:35:24 +08:00
|
|
|
|
|
|
|
|
|
|
```ts
|
2026-04-27 11:58:17 +08:00
|
|
|
|
const results = await ImSDK.searchMessages({
|
|
|
|
|
|
keyword: '关键字',
|
|
|
|
|
|
msgType: 'TEXT', // 可选,过滤消息类型
|
|
|
|
|
|
startTime: '2026-01-01', // 可选,时间范围
|
|
|
|
|
|
endTime: '2026-12-31',
|
|
|
|
|
|
})
|
|
|
|
|
|
```
|
2026-04-24 15:35:24 +08:00
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
### 10. App 版本更新
|
2026-04-24 15:35:24 +08:00
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
```ts
|
|
|
|
|
|
import { UpdateSDK } from '@xuqm/rn-sdk'
|
2026-04-24 15:35:24 +08:00
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
// 自动读取原生版本码,无需传参
|
|
|
|
|
|
const info = await UpdateSDK.checkAppUpdate()
|
|
|
|
|
|
if (info?.needsUpdate) {
|
|
|
|
|
|
console.log(info.versionName, info.forceUpdate, info.downloadUrl)
|
|
|
|
|
|
}
|
2026-04-24 15:35:24 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
### 11. RN Bundle 热更新
|
2026-04-24 15:35:24 +08:00
|
|
|
|
|
|
|
|
|
|
```ts
|
2026-04-27 11:58:17 +08:00
|
|
|
|
// 插件在 bundle 加载时自注册(自动读取 plugin.json)
|
|
|
|
|
|
import meta from './plugin.json' // { moduleId, version }
|
|
|
|
|
|
UpdateSDK.registerPlugin(meta)
|
|
|
|
|
|
|
|
|
|
|
|
// 检查 → 下载 → 缓存(三步)
|
|
|
|
|
|
const checkInfo = await UpdateSDK.checkRnUpdate('home')
|
|
|
|
|
|
if (checkInfo.needsUpdate) {
|
|
|
|
|
|
const source = await UpdateSDK.downloadRnBundle(checkInfo.downloadUrl)
|
|
|
|
|
|
await UpdateSDK.cacheRnBundle('home', checkInfo.latestVersion, checkInfo.md5, source)
|
|
|
|
|
|
}
|
2026-04-24 15:35:24 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
## 消息类型 content 格式
|
2026-04-24 15:35:24 +08:00
|
|
|
|
|
|
|
|
|
|
| MsgType | content |
|
|
|
|
|
|
|---------|---------|
|
|
|
|
|
|
| `TEXT` | 纯文本字符串 |
|
2026-04-27 11:58:17 +08:00
|
|
|
|
| `IMAGE` | `{"url":"...","thumbnailUrl":"...","width":800,"height":600}` |
|
|
|
|
|
|
| `VIDEO` | `{"url":"...","thumbnailUrl":"...","duration":30,"size":1048576}` |
|
2026-04-24 15:35:24 +08:00
|
|
|
|
| `AUDIO` | `{"url":"...","duration":12,"size":204800}` |
|
|
|
|
|
|
| `FILE` | `{"url":"...","name":"report.pdf","size":512000,"mimeType":"application/pdf"}` |
|
2026-04-27 11:58:17 +08:00
|
|
|
|
| `LOCATION` | `{"lat":39.9042,"lng":116.4074,"address":"北京市","title":"天安门"}` |
|
2026-04-24 15:35:24 +08:00
|
|
|
|
| `CUSTOM` | 任意 JSON 字符串 |
|
2026-04-27 11:58:17 +08:00
|
|
|
|
| `NOTIFY` | `{"title":"系统通知","content":"内容","level":"INFO"}` |
|
2026-04-24 15:35:24 +08:00
|
|
|
|
| `RICH_TEXT` | `{"html":"<b>加粗</b>内容"}` |
|
|
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
## TypeScript 类型
|
2026-04-24 15:35:24 +08:00
|
|
|
|
|
|
|
|
|
|
```ts
|
|
|
|
|
|
interface ImMessage {
|
2026-04-27 11:58:17 +08:00
|
|
|
|
id: string
|
|
|
|
|
|
appId: string
|
|
|
|
|
|
fromUserId: string
|
|
|
|
|
|
toId: string
|
|
|
|
|
|
chatType: 'SINGLE' | 'GROUP'
|
|
|
|
|
|
msgType: MsgType
|
|
|
|
|
|
content: string
|
|
|
|
|
|
status: 'SENT' | 'DELIVERED' | 'READ' | 'REVOKED'
|
|
|
|
|
|
mentionedUserIds?: string
|
|
|
|
|
|
createdAt: string // ISO 8601
|
2026-04-24 15:35:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-27 11:58:17 +08:00
|
|
|
|
interface ConversationData {
|
|
|
|
|
|
targetId: string
|
|
|
|
|
|
chatType: 'SINGLE' | 'GROUP'
|
|
|
|
|
|
lastMsgContent: string
|
|
|
|
|
|
lastMsgType: string
|
|
|
|
|
|
lastMsgTime: number // Unix ms
|
|
|
|
|
|
unreadCount: number
|
|
|
|
|
|
isMuted: boolean
|
|
|
|
|
|
isPinned: boolean
|
2026-04-24 15:35:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
```
|