XuqmGroup-RNSDK/docs/SDK-API参考.md
XuqmGroup ab30b28f3d feat: v0.3.0 — 自动初始化 + 插件更新 + 脚手架工具
common:
- 新增 autoInit.ts 自动初始化(对齐 Android ContentProvider 模式)
- 新增 configCrypto.ts 内置配置文件解密
- XuqmSDK 新增 initWithConfigFile / setUserInfo / getUserInfo
- 新增 crypto-types.d.ts Web Crypto 类型声明

update:
- 重写 UpdateSDK:checkAppUpdate / checkPluginUpdate / checkAndCachePlugin
- 移除 checkAndPromptAppUpdate(SDK 不做 UI)
- 新增插件脚手架 create-plugin.mjs
- 重命名 RnUpdateInfo → PluginUpdateInfo

license:
- crypto.ts 支持 XUQM-CONFIG-V1 + XUQM-LICENSE-V1 双格式
- 新增 decryptConfigFile 导出

docs:
- 重写 README.md
- 新增 docs/SDK-API参考.md
- 新增 docs/插件脚手架.md
- 新增 docs/配置文件规范.md
2026-06-15 01:44:20 +08:00

847 行
30 KiB
Markdown

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

# XuqmGroup RN SDK API 参考
> 版本:基于源码自动生成,最后更新 2026-06-15
>
> 包名:`@xuqm/rn-common` · `@xuqm/rn-update` · `@xuqm/rn-xwebview` · `@xuqm/rn-push` · `@xuqm/rn-im` · `@xuqm/rn-license`
---
## 1. XuqmSDKcommon
> `import { XuqmSDK } from '@xuqm/rn-common'`
SDK 核心初始化模块。所有其他 SDK 模块依赖 XuqmSDK 完成初始化后才能正常工作。
### 1.1 类型定义
```ts
interface XuqmInitOptions {
appKey: string; // 应用标识(从租户平台获取)
debug?: boolean; // 是否开启调试日志
}
interface XuqmConfig {
appKey: string;
apiUrl: string;
imWsUrl: string;
fileServiceUrl: string;
debug: boolean;
}
interface XuqmUserInfo {
userId?: string;
name?: string;
email?: string;
phone?: string;
}
```
### 1.2 API 方法
#### `XuqmSDK.initialize(options): Promise<void>`
异步初始化。从租户平台拉取远程配置IM WebSocket URL、文件服务 URL 等),失败时回退到内置默认地址。
```ts
await XuqmSDK.initialize({ appKey: "your-app-key", debug: __DEV__ });
```
#### `XuqmSDK.init(options): void`
同步初始化(不拉取远程配置,直接使用内置默认 URL。适用于网络不可用或无需远程配置的场景。
```ts
XuqmSDK.init({ appKey: "your-app-key" });
```
#### `XuqmSDK.initializeFromLicense(file, options?): void`
从已解密的 License 文件对象初始化。通常配合 License SDK 使用。
```ts
interface LicenseFile {
appKey: string;
baseUrl?: string;
serverUrl?: string;
}
XuqmSDK.initializeFromLicense(decryptedFile, { debug: false });
```
#### `XuqmSDK.initWithConfigFile(encryptedContent, options?): Promise<void>`
从加密配置文件(`.xuqmconfig`初始化。SDK 自动解密并初始化,支持 `XUQM-CONFIG-V1``XUQM-LICENSE-V1` 两种格式。
```ts
import config from "./assets/app.xuqmconfig";
await XuqmSDK.initWithConfigFile(config);
```
#### `XuqmSDK.awaitInitialization(): Promise<void>`
等待初始化完成。在异步初始化场景下,其他模块可调用此方法确保 SDK 已就绪。
```ts
await XuqmSDK.awaitInitialization();
```
#### `XuqmSDK.setUserId(userId): void`
设置当前用户 ID。登录成功后调用。
```ts
XuqmSDK.setUserId("user-123");
```
#### `XuqmSDK.getUserId(): string | null`
获取当前用户 ID。
#### `XuqmSDK.setUserInfo(info): void`
设置用户信息(用于灰度发布和 License 验证)。登录成功后调用,同时会自动同步 `userId`
```ts
XuqmSDK.setUserInfo({ userId: "user-123", name: "张三", phone: "13800138000" });
```
#### `XuqmSDK.getUserInfo(): XuqmUserInfo | null`
获取当前用户信息。
### 1.3 独立导出
```ts
import { awaitInitialization } from "@xuqm/rn-common";
// 等同于 XuqmSDK.awaitInitialization()
```
---
## 2. UpdateSDKupdate
> `import { UpdateSDK } from '@xuqm/rn-update'`
应用整包更新 + RN 插件Bundle热更新。
### 2.1 类型定义
```ts
interface PluginMeta {
moduleId: string; // 插件唯一标识,如 'buz1'
version: string; // 当前 bundle 版本号
}
interface AppUpdateInfo {
needsUpdate: boolean;
versionName?: string; // 最新版本名,如 '2.1.0'
versionCode?: number; // 最新版本号(整数)
downloadUrl?: string; // APK 直接下载地址
changeLog?: string; // 更新日志
forceUpdate?: boolean; // 是否强制更新
appStoreUrl?: string; // iOS App Store 地址
marketUrl?: string; // Android 应用商店地址
requiresLogin?: boolean; // 服务端要求登录后才能检查
alreadyDownloaded?: boolean; // APK 是否已下载(仅 Android
apkHash?: string | null; // APK SHA-256 校验值
}
interface PluginUpdateInfo {
needsUpdate: boolean;
latestVersion: string;
downloadUrl: string;
md5: string;
minCommonVersion: string; // 要求的最低 common bundle 版本
note: string;
}
interface CachedRnBundle {
moduleId: string;
version: string;
md5: string;
downloadedAt: string;
source: string;
}
```
### 2.2 API 方法
#### `UpdateSDK.registerPlugin(meta): void`
注册插件元数据。在插件 bundle 入口文件顶部调用。
```ts
// src/plugins/buz1/bundle.ts
UpdateSDK.registerPlugin({ moduleId: "buz1", version: "1.0.0" });
```
#### `UpdateSDK.getRegisteredPluginVersion(moduleId): string | undefined`
获取已注册的插件版本号。
#### `UpdateSDK.getRegisteredPlugins(): PluginMeta[]`
获取所有已注册的插件列表。
#### `UpdateSDK.checkAppUpdate(bypassIgnore?): Promise<AppUpdateInfo>`
检查 App 整包更新。自动检测平台iOS/Android并传给服务端。
- `bypassIgnore = false`(默认):静默检查,跳过用户已忽略的版本
- `bypassIgnore = true`:用户主动检查,不跳过
```ts
const info = await UpdateSDK.checkAppUpdate(true);
if (info.needsUpdate && info.forceUpdate) {
// 强制更新
}
```
#### `UpdateSDK.openStore(appStoreUrl?, marketUrl?): Promise<void>`
打开应用商店。iOS 使用 `appStoreUrl`,Android 使用 `marketUrl`
#### `UpdateSDK.checkPluginUpdate(moduleId): Promise<PluginUpdateInfo>`
检查指定插件的更新。插件必须已通过 `registerPlugin()` 注册。
```ts
const info = await UpdateSDK.checkPluginUpdate("buz1");
if (info.needsUpdate) {
// 下载并缓存
}
```
#### `UpdateSDK.downloadPluginBundle(downloadUrl): Promise<string>`
下载插件 bundle 源码文本。
#### `UpdateSDK.cachePluginBundle(moduleId, version, md5, source): Promise<CachedRnBundle>`
缓存插件 bundle 到本地AsyncStorage
#### `UpdateSDK.getCachedPluginBundle(moduleId): Promise<CachedRnBundle | null>`
读取已缓存的插件 bundle。
#### `UpdateSDK.checkAndCachePlugin(moduleId): Promise<CachedRnBundle | null>`
检查并下载插件更新(一步完成)。有更新时下载并缓存,无更新返回 `null`。调用方需在下次启动时通过 `reloadPlugin()` 加载新版本。
```ts
const cached = await UpdateSDK.checkAndCachePlugin("buz1");
if (cached) {
// 下次启动生效
}
```
#### `UpdateSDK.getAppVersionCode(): number`
当前 App versionCode原生读取
#### `UpdateSDK.getAppVersionName(): string`
当前 App versionName原生读取
#### `UpdateSDK._devSetAppVersion(versionCode, versionName?): void`
开发环境手动设置版本号(仅调试用,生产环境不要调用)。
---
## 3. XWebViewxwebview
> `import { XWebViewScreen, XWebViewView, XWebViewConfig, ... } from '@xuqm/rn-xwebview'`
WebView 容器组件,支持导航栏、文件下载、JS Bridge 等。
### 3.1 类型定义
```ts
type XWebViewConfig = {
showTopBar?: boolean; // 是否显示顶部导航栏
showStatusBar?: boolean; // 是否显示状态栏
doubleBackExit?: boolean; // 双击返回退出
title?: string; // 自定义标题
showTitle?: boolean; // 是否显示标题
autoTitle?: boolean; // 自动从网页获取标题
showMenu?: boolean; // 是否显示菜单按钮
openForBrowser?: boolean; // 是否用外部浏览器打开
clickMenu?: XWebViewClickMenu; // 自定义菜单
url?: string; // 加载的 URL
content?: string; // 加载的 HTML 内容
onMessage?: (event: XWebViewMessageEvent) => void; // 接收 Web 消息
injectedJavaScript?: string; // 注入的 JS
onPermissionRequest?: (request: XWebViewPermissionRequest) => void;
autoDownload?: boolean; // 自动下载
onDownloadStart?: (request: XWebViewDownloadRequest) => void;
onDownloadProgress?: (progress: XWebViewDownloadProgress) => void;
onDownloadComplete?: (result: XWebViewDownloadResult) => void;
onDownloadError?: (url: string, error: string) => void;
onDownloadDecide?: (
request: XWebViewDownloadRequest,
) => XWebViewDownloadDecision | Promise<XWebViewDownloadDecision>;
downloadConflict?: "rename" | "overwrite";
onClose?: () => void;
};
type XWebViewControllerAPI = {
refresh: () => void;
close: () => void;
goBack: () => void;
goForward: () => void;
copyUrl: () => void;
postMessageToWeb: (jsString: string) => void;
getTitle: () => string;
};
type XWebViewClickMenu = { view?: React.ReactNode; onClick: () => void };
type XWebViewMessageEvent = { nativeEvent: { data: string } };
type XWebViewPermissionRequest = {
origin: string;
resources: string[];
grant: (resources?: string[]) => void;
deny: () => void;
};
type XWebViewDownloadRequest = {
url: string;
suggestedFilename: string;
mimeType?: string;
fileSize?: number;
};
type XWebViewDownloadDecision = {
allowed: boolean;
filename?: string;
savePath?: string;
};
type XWebViewDownloadProgress = {
url: string;
filename: string;
received: number;
total: number;
percentage: number;
};
type XWebViewDownloadResult = {
url: string;
filename: string;
filePath: string;
fileSize: number;
};
```
### 3.2 组件
#### `<XWebViewScreen />`
全屏 WebView 页面组件,带顶部导航栏(返回、关闭、菜单)。作为独立屏幕使用,通过导航跳转进入。
#### `<XWebViewView />`
嵌入式 WebView 组件,无顶部导航栏。适用于嵌入到其他页面中。
### 3.3 桥接函数
#### `openXWebView(navigate, config): void`
打开 XWebView 页面。调用后会设置配置并执行导航。
```ts
import { openXWebView } from "@xuqm/rn-xwebview";
openXWebView(navigation.navigate, {
url: "https://example.com",
title: "详情",
showTopBar: true,
});
```
#### `getXWebViewConfig(): XWebViewConfig`
获取当前 XWebView 配置(由 `openXWebView` 设置)。
#### `setXWebViewController(controller: XWebViewControllerAPI | null): void`
设置 XWebView 控制器实例(由组件内部调用)。
#### `XWebViewControl: XWebViewControllerAPI`
全局 WebView 控制代理。可调用 `refresh()`、`close()`、`goBack()`、`goForward()`、`copyUrl()`、`postMessageToWeb(js)`、`getTitle()` 等方法控制当前 WebView。
```ts
import { XWebViewControl } from "@xuqm/rn-xwebview";
XWebViewControl.postMessageToWeb('window.dispatchEvent(new Event("refresh"))');
XWebViewControl.close();
```
### 3.4 子组件
#### `XWebViewProgress`
WebView 加载进度条组件。
---
## 4. PushSDKpush
> `import { PushSDK } from '@xuqm/rn-push'`
推送服务 SDK,支持华为、小米、OPPO、vivo、荣耀、FCMAndroid和 APNsiOS
### 4.1 类型定义
```ts
type PushVendor =
| "HUAWEI"
| "XIAOMI"
| "OPPO"
| "VIVO"
| "HONOR"
| "FCM"
| "APNS";
```
### 4.2 API 方法
#### `PushSDK.initialize(userId?): Promise<void>`
初始化推送服务。如果已有缓存的 token 且用户匹配,自动注册到服务端。
```ts
await PushSDK.initialize("user-123");
```
#### `PushSDK.setPendingToken(token, vendor?): void`
缓存设备 token不立即注册。适用于原生层在用户登录前就收到 token 的场景。
```ts
PushSDK.setPendingToken(token, "HUAWEI");
```
#### `PushSDK.getPendingToken(): { token: string; vendor?: PushVendor } | null`
获取当前缓存的 pending token。
#### `PushSDK.setDeviceToken(token, vendor?): Promise<void>`
设置设备 token 并立即尝试注册到服务端。
#### `PushSDK.requestNativeRegistration(): Promise<void>`
触发原生推送注册。Android 尝试注册厂商 SDK,iOS 请求 APNs 注册。通过 `onPushToken()` 监听 token 回调。
#### `PushSDK.onPushToken(callback): () => void`
监听原生层推送 token。返回取消监听函数。
```ts
const unsubscribe = PushSDK.onPushToken((token, vendor) => {
PushSDK.setDeviceToken(token, vendor as PushVendor);
});
```
#### `PushSDK.registerToken(userId, token, vendor?): Promise<void>`
注册推送设备 token 到服务端。vendor 缺省时自动检测设备品牌。
```ts
await PushSDK.registerToken("user-123", deviceToken, "HUAWEI");
```
#### `PushSDK.unregisterToken(userId): Promise<void>`
注销用户的推送 token。
#### `PushSDK.logout(userId?): Promise<void>`
登出推送服务(内部调用 `unregisterToken`。userId 缺省时使用当前用户。
---
## 5. ImSDKim
> `import { ImSDK } from '@xuqm/rn-im'`
即时通讯 SDK,提供登录、消息收发、会话管理、群组、好友等功能。
### 5.1 核心类型
```ts
type ChatType = "SINGLE" | "GROUP";
type MsgType =
| "TEXT"
| "IMAGE"
| "VIDEO"
| "AUDIO"
| "FILE"
| "CUSTOM"
| "LOCATION"
| "NOTIFY"
| "RICH_TEXT"
| "CALL_AUDIO"
| "CALL_VIDEO"
| "QUOTE"
| "MERGE"
| "REVOKED"
| "FORWARD";
type MsgStatus =
| "SENDING"
| "SENT"
| "DELIVERED"
| "READ"
| "FAILED"
| "REVOKED";
interface ImMessage {
id: string;
appKey: string;
fromUserId: string;
fromId?: string;
toId: string;
chatType: ChatType;
msgType: MsgType;
content: string;
status: MsgStatus;
mentionedUserIds?: string;
groupReadCount?: number;
revoked?: boolean;
createdAt: number;
editedAt?: number | null;
}
interface ImGroup {
id: string;
appKey: string;
name: string;
groupType?: string;
creatorId: string;
memberIds: string;
adminIds: string;
announcement?: string | null;
memberInfo?: string | null;
extAttributes?: string | null;
createdAt: number;
}
interface ConversationData {
targetId: string;
chatType: ChatType;
lastMsgContent?: string | null;
lastMsgType?: string | null;
lastMsgTime: number;
unreadCount: number;
isMuted: boolean;
isPinned: boolean;
conversationGroup?: string | null;
}
interface UserProfile {
id?: string;
appKey?: string;
userId: string;
nickname?: string | null;
avatar?: string | null;
gender?: string | null;
status?: string | null;
createdAt?: number | null;
}
interface FriendRequest {
id: string;
appKey: string;
fromUserId: string;
toUserId: string;
remark?: string | null;
status: "PENDING" | "ACCEPTED" | "REJECTED";
createdAt: number;
reviewedAt?: number | null;
}
interface GroupJoinRequest {
id: string;
appKey: string;
groupId: string;
requesterId: string;
remark?: string | null;
status: "PENDING" | "ACCEPTED" | "REJECTED";
createdAt: number;
reviewedAt?: number | null;
}
interface ImEventListener {
onConnected?: () => void;
onDisconnected?: (reason?: string) => void;
onMessage?: (msg: ImMessage) => void;
onGroupMessage?: (msg: ImMessage) => void;
onSystemMessage?: (msg: ImMessage) => void;
onRead?: (msg: ImMessage) => void;
onRevoke?: (data: { msgId: string; operatorId: string }) => void;
onError?: (error: string) => void;
}
```
### 5.2 连接与认证
| 方法 | 签名 | 说明 |
| ------------- | ---------------------------------------------------- | --------------------------------- |
| `login` | `(userId: string, userSig: string) => Promise<void>` | 登录 IM 服务,建立 WebSocket 连接 |
| `reconnect` | `() => Promise<void>` | 重新连接(使用已保存的 token |
| `disconnect` | `() => void` | 断开连接并清理状态 |
| `isConnected` | `() => boolean` | 是否已连接 |
### 5.3 消息发送
| 方法 | 签名 | 说明 |
| ---------------------- | ------------------------------------------------------------------ | ------------ |
| `sendMessage` | `(params: SendMessageParams) => Promise<ImMessage>` | 通用发送 |
| `sendTextMessage` | `(toId, chatType, text) => Promise<ImMessage>` | 文本消息 |
| `sendImageMessage` | `(toId, chatType, imageUri) => Promise<ImMessage>` | 图片消息 |
| `sendVideoMessage` | `(toId, chatType, videoUri) => Promise<ImMessage>` | 视频消息 |
| `sendAudioMessage` | `(toId, chatType, audioUri) => Promise<ImMessage>` | 语音消息 |
| `sendFileMessage` | `(toId, chatType, fileUri) => Promise<ImMessage>` | 文件消息 |
| `sendNotifyMessage` | `(toId, chatType, content) => Promise<ImMessage>` | 通知消息 |
| `sendQuoteMessage` | `(toId, chatType, content, quotedMsgId) => Promise<ImMessage>` | 引用消息 |
| `sendMergeMessage` | `(toId, chatType, title, summary, messages) => Promise<ImMessage>` | 合并转发 |
| `sendCallAudioMessage` | `(toId, chatType, content) => Promise<ImMessage>` | 语音通话消息 |
| `sendCallVideoMessage` | `(toId, chatType, content) => Promise<ImMessage>` | 视频通话消息 |
| `sendCustomMessage` | `(toId, chatType, content) => Promise<ImMessage>` | 自定义消息 |
| `sendLocationMessage` | `(toId, chatType, ...) => Promise<ImMessage>` | 位置消息 |
| `sendRichTextMessage` | `(toId, chatType, content) => Promise<ImMessage>` | 富文本消息 |
| `sendForwardMessage` | `(toId, chatType, messageId) => Promise<ImMessage>` | 转发消息 |
### 5.4 消息操作
| 方法 | 签名 | 说明 |
| ------------------------------ | --------------------------------------------------------------- | --------------------- |
| `revokeMessage` | `(messageId: string) => Promise<ImMessage>` | 撤回消息 |
| `editMessage` | `(messageId: string, content: string) => Promise<ImMessage>` | 编辑消息 |
| `fetchHistory` | `(toId, page?, size?) => Promise<ImMessage[]>` | 获取单聊历史消息 |
| `fetchHistoryWithFilters` | `(toId, params) => Promise<PageResult<ImMessage>>` | 带筛选的历史消息 |
| `fetchGroupHistory` | `(groupId, page?, size?) => Promise<ImMessage[]>` | 获取群聊历史消息 |
| `fetchGroupHistoryWithFilters` | `(groupId, params) => Promise<PageResult<ImMessage>>` | 带筛选的群聊历史 |
| `locateHistoryPage` | `(toId, messageId, size?) => Promise<PageResult<ImMessage>>` | 定位到指定消息所在页 |
| `locateGroupHistoryPage` | `(groupId, messageId, size?) => Promise<PageResult<ImMessage>>` | 群聊定位到指定消息 |
| `syncOfflineMessages` | `(maxCount?) => Promise<ImMessage[]>` | 同步离线消息 |
| `offlineMessageCount` | `() => Promise<number>` | 离线消息数量 |
| `searchMessages` | `(params) => Promise<...>` | 搜索本地消息(需 DB |
### 5.5 会话管理
| 方法 | 签名 | 说明 |
| -------------------------------- | --------------------------------------------------- | ---------------------- |
| `listConversations` | `() => Promise<ConversationData[]>` | 获取会话列表 |
| `subscribeConversations` | `(callback) => () => void` | 订阅会话列表变化 |
| `markRead` | `(targetId, chatType?) => Promise<void>` | 标记已读 |
| `setConversationMuted` | `(targetId, chatType, muted) => Promise<void>` | 设置免打扰 |
| `setConversationPinned` | `(targetId, chatType, pinned) => Promise<void>` | 设置置顶 |
| `setDraft` | `(targetId, chatType, draft) => Promise<void>` | 保存草稿 |
| `getDraft` | `(targetId, chatType) => Promise<string>` | 获取草稿 |
| `setConversationHidden` | `(targetId, chatType, hidden) => Promise<void>` | 隐藏会话 |
| `setConversationGroup` | `(targetId, chatType, groupName?) => Promise<void>` | 设置会话分组 |
| `listConversationGroups` | `() => Promise<string[]>` | 获取会话分组列表 |
| `listConversationGroupItems` | `(groupName) => Promise<ConversationGroupItem[]>` | 获取分组下的会话 |
| `deleteConversation` | `(targetId, chatType) => Promise<void>` | 删除会话 |
| `getTotalUnreadCount` | `() => Promise<number>` | 获取总未读数 |
| `syncHistoryForAllConversations` | `() => Promise<void>` | 同步所有会话的历史消息 |
### 5.6 群组管理
| 方法 | 签名 | 说明 |
| ------------------------- | ------------------------------------------------------------- | -------------------- |
| `createGroup` | `(name, memberIds, groupType?) => Promise<ImGroup>` | 创建群组 |
| `listGroups` | `() => Promise<ImGroup[]>` | 获取已加入的群组列表 |
| `listPublicGroups` | `(keyword?) => Promise<ImGroup[]>` | 搜索公开群组 |
| `getGroupInfo` | `(groupId) => Promise<ImGroup>` | 获取群组详情 |
| `listGroupMembers` | `(groupId) => Promise<UserProfile[]>` | 获取群成员列表 |
| `searchGroupMembers` | `(groupId, keyword, size?) => Promise<UserProfile[]>` | 搜索群成员 |
| `updateGroupInfo` | `(groupId, name?, announcement?) => Promise<ImGroup>` | 更新群信息 |
| `addGroupMember` | `(groupId, userId) => Promise<ImGroup>` | 添加群成员 |
| `removeGroupMember` | `(groupId, targetUserId) => Promise<ImGroup>` | 移除群成员 |
| `batchAddGroupMembers` | `(groupId, userIds) => Promise<void>` | 批量添加群成员 |
| `batchRemoveGroupMembers` | `(groupId, userIds) => Promise<void>` | 批量移除群成员 |
| `leaveGroup` | `(groupId) => Promise<ImGroup>` | 退出群组 |
| `setGroupRole` | `(groupId, userId, role) => Promise<ImGroup>` | 设置群成员角色 |
| `muteGroupMember` | `(groupId, userId, minutes) => Promise<ImGroup>` | 禁言群成员 |
| `transferGroupOwner` | `(groupId, newOwnerId) => Promise<ImGroup>` | 转让群主 |
| `updateGroupAttributes` | `(groupId, attributes) => Promise<ImGroup>` | 更新群属性 |
| `removeGroupAttributes` | `(groupId, keys) => Promise<ImGroup>` | 删除群属性 |
| `dismissGroup` | `(groupId) => Promise<void>` | 解散群组 |
| `modifyGroupMemberInfo` | `(groupId, userId, nickname?, role?) => Promise<void>` | 修改群成员信息 |
| `adminGroupReadReceipts` | `(groupId, messageIds) => Promise<GroupReadReceiptSummary[]>` | 群消息已读回执 |
### 5.7 群组加入请求
| 方法 | 签名 | 说明 |
| ------------------------------ | --------------------------------------------------- | ---------------- |
| `sendGroupJoinRequest` | `(groupId, remark?) => Promise<GroupJoinRequest>` | 发送入群申请 |
| `listGroupJoinRequests` | `(groupId) => Promise<GroupJoinRequest[]>` | 获取入群申请列表 |
| `acceptGroupJoinRequest` | `(groupId, requestId) => Promise<GroupJoinRequest>` | 同意入群申请 |
| `rejectGroupJoinRequest` | `(groupId, requestId) => Promise<GroupJoinRequest>` | 拒绝入群申请 |
| `batchAcceptGroupJoinRequests` | `(groupId, requestIds) => Promise<void>` | 批量同意 |
| `batchRejectGroupJoinRequests` | `(groupId, requestIds) => Promise<void>` | 批量拒绝 |
### 5.8 好友管理
| 方法 | 签名 | 说明 |
| --------------------------- | ----------------------------------------------- | ---------------- |
| `listFriends` | `() => Promise<string[]>` | 获取好友列表 |
| `addFriend` | `(friendId) => Promise<void>` | 添加好友 |
| `removeFriend` | `(friendId) => Promise<void>` | 删除好友 |
| `removeAllFriends` | `() => Promise<void>` | 删除所有好友 |
| `batchAddFriends` | `(friendIds) => Promise<void>` | 批量添加好友 |
| `batchRemoveFriends` | `(friendIds) => Promise<void>` | 批量删除好友 |
| `setFriendGroup` | `(friendId, groupName?) => Promise<void>` | 设置好友分组 |
| `listFriendGroups` | `() => Promise<string[]>` | 获取好友分组列表 |
| `listFriendsByGroup` | `(groupName) => Promise<string[]>` | 按分组获取好友 |
| `listFriendRequests` | `(direction?) => Promise<FriendRequest[]>` | 获取好友请求列表 |
| `sendFriendRequest` | `(toUserId, remark?) => Promise<FriendRequest>` | 发送好友请求 |
| `acceptFriendRequest` | `(requestId) => Promise<FriendRequest>` | 同意好友请求 |
| `rejectFriendRequest` | `(requestId) => Promise<FriendRequest>` | 拒绝好友请求 |
| `batchAcceptFriendRequests` | `(requestIds) => Promise<void>` | 批量同意 |
| `batchRejectFriendRequests` | `(requestIds) => Promise<void>` | 批量拒绝 |
### 5.9 黑名单
| 方法 | 签名 | 说明 |
| --------------------- | ------------------------------------------------- | -------------- |
| `listBlacklist` | `() => Promise<BlacklistEntry[]>` | 获取黑名单 |
| `addToBlacklist` | `(blockedUserId) => Promise<BlacklistEntry>` | 加入黑名单 |
| `removeFromBlacklist` | `(blockedUserId) => Promise<void>` | 移出黑名单 |
| `checkBlacklist` | `(targetUserId) => Promise<BlacklistCheckResult>` | 检查黑名单状态 |
### 5.10 用户资料
| 方法 | 签名 | 说明 |
| --------------- | --------------------------------------------------------------- | ------------ |
| `getProfile` | `(userId) => Promise<UserProfile>` | 获取用户资料 |
| `updateProfile` | `(userId, nickname?, avatar?, gender?) => Promise<UserProfile>` | 更新用户资料 |
| `searchUsers` | `(keyword, size?) => Promise<UserProfile[]>` | 搜索用户 |
### 5.11 事件监听
| 方法 | 签名 | 说明 |
| ------------------ | ------------------------------------- | ---------------- |
| `addListener` | `(listener: ImEventListener) => void` | 添加事件监听器 |
| `removeListener` | `(listener: ImEventListener) => void` | 移除事件监听器 |
| `subscribeGroup` | `(groupId) => void` | 订阅群组消息 |
| `unsubscribeGroup` | `(groupId) => void` | 取消订阅群组消息 |
---
## 6. Licenselicense
> `import * as License from '@xuqm/rn-license'`
设备 License 验证模块,支持离线缓存和自动注册。
### 6.1 类型定义
```ts
interface LicenseFile {
appKey: string;
appName?: string;
companyName?: string;
baseUrl?: string;
issuedAt?: string;
expiresAt?: string;
}
interface LicenseUserInfo {
userId?: string;
name?: string;
email?: string;
phone?: string;
}
type LicenseStatus = "ok" | "denied" | "unknown";
type LicenseResult =
| { type: "success"; reason: string }
| { type: "error"; message: string };
```
### 6.2 API 方法
#### `initialize(appKey, options?): void`
初始化 License SDK。
```ts
License.initialize("your-app-key", {
baseUrl: "https://auth.xuqinmin.com",
deviceName: "My Device",
});
```
#### `initializeFromFile(encryptedContent): Promise<void>`
从加密 License 文件初始化。自动解密并提取 `appKey``baseUrl`
```ts
import licenseFile from "./assets/license.xuqmconfig";
await License.initializeFromFile(licenseFile);
```
#### `checkLicense(userInfo?): Promise<LicenseResult>`
检查 License 状态。优先使用内存缓存10 分钟有效期),其次持久化缓存,最后请求服务端验证。服务端流程:先尝试 verify已有 token,失败则 register注册新设备
```ts
const result = await License.checkLicense({ userId: "user-123", name: "张三" });
if (result.type === "error") {
console.error(result.message);
}
```
#### `getStatus(): Promise<LicenseStatus>`
获取当前 License 状态(`'ok'` / `'denied'` / `'unknown'`)。
#### `getDeviceId(): Promise<string>`
获取设备 ID首次生成后持久化存储
#### `clear(): Promise<void>`
清除所有 License 缓存状态、token、设备 ID
---
## 快速参考
### 初始化顺序
```ts
// 1. 初始化核心 SDK
await XuqmSDK.initialize({ appKey: "xxx" });
// 或从加密文件初始化
await XuqmSDK.initWithConfigFile(encryptedConfig);
// 2. 登录后设置用户信息
XuqmSDK.setUserInfo({ userId, name, phone });
// 3. 初始化推送
PushSDK.onPushToken((token, vendor) => {
PushSDK.setDeviceToken(token, vendor);
});
await PushSDK.initialize(userId);
// 4. 登录 IM
await ImSDK.login(userId, userSig);
// 5. 检查更新
const appUpdate = await UpdateSDK.checkAppUpdate();
const pluginUpdate = await UpdateSDK.checkAndCachePlugin("buz1");
```
### 包依赖关系
```
@xuqm/rn-common ← XuqmSDK, 配置, HTTP, 工具函数(其他包的底层依赖)
@xuqm/rn-im ← ImSDK依赖 common
@xuqm/rn-push ← PushSDK依赖 common
@xuqm/rn-update ← UpdateSDK依赖 common
@xuqm/rn-xwebview ← XWebView 组件(依赖 common
@xuqm/rn-license ← License依赖 common
```