T-B01: XuqmBundleModule 原生模块 - Android: XuqmBundleModule.java(文件读写/manifest/路径) - iOS: XuqmBundleModule.m(对应实现) - JS: NativeBundle.ts 封装 - 注册到 XuqmUpdatePackage T-B02: downloadPluginBundle 添加 onProgress - 使用 ReadableStream 实现下载进度追踪 - checkAndCachePlugin 同步支持 onProgress T-B03: XWebView JSBridge 标准接口文档 - docs/XWebView-JSBridge.md - H5→RN 消息协议 / RN→H5 通信 - 下载处理 / Dialog 覆盖 / 标准 Bridge 接口 T-B04: PushSDK Android 厂商集成文档 - docs/PushSDK-厂商集成.md - 6 厂商配置步骤 / ProGuard 规则 / 调试指南
341 行
11 KiB
Markdown
341 行
11 KiB
Markdown
# XuqmGroup React Native SDK
|
|
|
|
Modular React Native SDK providing IM, Push, App/Plugin Update, WebView, and License management for XuqmGroup platform applications.
|
|
|
|
## Table of Contents
|
|
|
|
- [Overview](#overview)
|
|
- [Package Structure](#package-structure)
|
|
- [Installation](#installation)
|
|
- [Quick Start](#quick-start)
|
|
- [Package Details](#package-details)
|
|
- [Development](#development)
|
|
- [Plugin Scaffolding](#plugin-scaffolding)
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
`@xuqm/rn-sdk` is the meta-package that re-exports all sub-modules. It provides a unified `XuqmSDK` entry point with coordinated login/logout that wires up IM, Push, and token management in a single call.
|
|
|
|
You can install the meta-package for full functionality, or pick individual packages as needed.
|
|
|
|
**Peer Dependencies** (required in host app):
|
|
|
|
| Package | Version |
|
|
|---------|---------|
|
|
| `react` | >= 18.0.0 |
|
|
| `react-native` | >= 0.76.0 |
|
|
| `@react-native-async-storage/async-storage` | >= 1.21.0 |
|
|
|
|
---
|
|
|
|
## Package Structure
|
|
|
|
```
|
|
XuqmGroup-RNSDK/ # @xuqm/rn-sdk (meta-package, private)
|
|
├── src/
|
|
│ ├── index.ts # Re-exports all sub-packages
|
|
│ └── sdk.ts # Unified login / logout
|
|
├── packages/
|
|
│ ├── common/ @xuqm/rn-common # Init, network, device, token, HTTP, auto-init
|
|
│ ├── im/ @xuqm/rn-im # IM messaging (WebSocket/STOMP + WatermelonDB)
|
|
│ ├── push/ @xuqm/rn-push # Multi-vendor push registration
|
|
│ ├── update/ @xuqm/rn-update # App update check + RN plugin hot-update
|
|
│ └── xwebview/ @xuqm/rn-xwebview # Enhanced WebView with JSBridge
|
|
```
|
|
|
|
All packages are at version **0.2.2**.
|
|
|
|
---
|
|
|
|
## Installation
|
|
|
|
### 1. Configure the npm registry
|
|
|
|
```bash
|
|
# In your host project root
|
|
cat > .npmrc << 'EOF'
|
|
registry=https://nexus.xuqinmin.com/repository/npm/
|
|
legacy-peer-deps=true
|
|
EOF
|
|
```
|
|
|
|
### 2. Install
|
|
|
|
**Option A -- Meta-package (all modules):**
|
|
|
|
```bash
|
|
yarn add @xuqm/rn-sdk
|
|
yarn add @react-native-async-storage/async-storage
|
|
```
|
|
|
|
**Option B -- Individual packages:**
|
|
|
|
```bash
|
|
yarn add @xuqm/rn-common @xuqm/rn-update @xuqm/rn-xwebview
|
|
yarn add @react-native-async-storage/async-storage
|
|
```
|
|
|
|
### 3. Install optional peer dependencies
|
|
|
|
```bash
|
|
# IM module (if using @xuqm/rn-im)
|
|
yarn add @nozbe/watermelondb
|
|
|
|
# XWebView module
|
|
yarn add react-native-webview react-native-blob-util react-native-svg
|
|
|
|
# Config file decryption (auto-init)
|
|
yarn add react-native-quick-crypto
|
|
```
|
|
|
|
---
|
|
|
|
## Quick Start
|
|
|
|
### Zero-config initialization (recommended)
|
|
|
|
Place an encrypted `.xuqmconfig` file (XUQM-CONFIG-V1 format) in your project, then add a Metro alias so the SDK can auto-discover it:
|
|
|
|
```js
|
|
// metro.config.js
|
|
const { getDefaultConfig } = require('metro-config');
|
|
module.exports = (async () => {
|
|
const config = await getDefaultConfig(__dirname);
|
|
config.resolver.extraNodeModules = {
|
|
'@xuqm/autoinit-config': './path/to/your.xuqmconfig',
|
|
};
|
|
return config;
|
|
})();
|
|
```
|
|
|
|
That is it. When `@xuqm/rn-common` is imported, it silently calls `XuqmSDK.initWithConfigFile()` using the encrypted file. No explicit init code needed.
|
|
|
|
### Manual initialization
|
|
|
|
```ts
|
|
import { XuqmSDK } from '@xuqm/rn-sdk';
|
|
|
|
// Init with appKey (fetches config from server)
|
|
await XuqmSDK.initialize({ appKey: 'your-app-key' });
|
|
|
|
// Login (wires up IM + Push automatically)
|
|
await XuqmSDK.login({ userId: 'user123', userSig: '...' });
|
|
|
|
// Logout
|
|
await XuqmSDK.logout();
|
|
```
|
|
|
|
### Using individual modules
|
|
|
|
```ts
|
|
import { ImSDK } from '@xuqm/rn-im';
|
|
import { PushSDK } from '@xuqm/rn-push';
|
|
import { UpdateSDK } from '@xuqm/rn-update';
|
|
import { XWebViewScreen } from '@xuqm/rn-xwebview';
|
|
```
|
|
|
|
---
|
|
|
|
## Package Details
|
|
|
|
### @xuqm/rn-common
|
|
|
|
Core module. Handles SDK initialization, HTTP requests, token persistence, device identification, and auto-initialization from encrypted config files.
|
|
|
|
| Export | Description |
|
|
|--------|-------------|
|
|
| `XuqmSDK.initialize(opts)` | Init with `appKey`, fetches remote config |
|
|
| `XuqmSDK.initWithConfigFile(encrypted)` | Init from `XUQM-CONFIG-V1` encrypted file |
|
|
| `XuqmSDK.initializeFromLicense(file)` | Init from decrypted config data |
|
|
| `XuqmSDK.awaitInitialization()` | Wait for async init to complete |
|
|
| `XuqmSDK.setUserId / getUserId` | Manage current user ID |
|
|
| `XuqmSDK.setUserInfo / getUserInfo` | Manage current user profile |
|
|
| `apiRequest(url, options?)` | HTTP request with Bearer token auth |
|
|
| `configureHttp(opts)` | Override HTTP base URL or headers |
|
|
| `getDeviceId()` | Stable per-install UUID |
|
|
| `getDeviceInfo()` | Device brand/model/OS info |
|
|
| `detectPushVendor()` | Detect push vendor from device brand |
|
|
| `ScaledImage` | Image component with aspect-ratio scaling |
|
|
| `isInitialized()` | Check if SDK is ready |
|
|
| `getConfig()` | Get resolved config |
|
|
|
|
**Auto-init mechanism:** On import, `autoInit.ts` tries `require('@xuqm/autoinit-config')`. If the Metro alias is configured, it decrypts the file and calls `initWithConfigFile` silently. If the alias is not configured, it skips without error.
|
|
|
|
**Encrypted config format:** `XUQM-CONFIG-V1.{base64url-salt}.{base64url-iv}.{base64url-ciphertext}` -- decrypted via PBKDF2 (120k iterations, SHA-256) + AES-256-GCM using `react-native-quick-crypto`.
|
|
|
|
---
|
|
|
|
### @xuqm/rn-im
|
|
|
|
Full-featured IM module. WebSocket/STOMP transport with WatermelonDB local persistence. Supports single and group chat with 15 message types.
|
|
|
|
**Message types:** `TEXT`, `IMAGE`, `VIDEO`, `AUDIO`, `FILE`, `CUSTOM`, `LOCATION`, `NOTIFY`, `RICH_TEXT`, `CALL_AUDIO`, `CALL_VIDEO`, `QUOTE`, `MERGE`, `REVOKED`, `FORWARD`
|
|
|
|
| Export | Description |
|
|
|--------|-------------|
|
|
| `ImSDK.login(userId, userSig)` | Connect to IM server |
|
|
| `ImSDK.disconnect()` | Disconnect |
|
|
| `ImSDK.sendMessage(params)` | Send a message |
|
|
| `ImSDK.getConversations()` | List conversations |
|
|
| `ImSDK.getHistory(query)` | Fetch message history |
|
|
| `ImSDK.createGroup(...)` | Create a group |
|
|
| `ImSDK.joinGroup(groupId)` | Join a group |
|
|
| `ImSDK.getGroupInfo(groupId)` | Get group details |
|
|
| `ImSDK.getGroupMembers(groupId)` | List group members |
|
|
| `listFriends / addFriend / removeFriend` | Friend management |
|
|
| `setFriendGroup / listFriendGroups` | Friend grouping |
|
|
| `checkBlacklist` | Blacklist check |
|
|
| `searchUsers / searchGroups / searchMessages` | Search |
|
|
| `editMessage` | Edit a sent message |
|
|
| `setConversationHidden / setConversationGroup` | Conversation management |
|
|
| `locateHistoryPage / locateGroupHistoryPage` | Jump to specific history page |
|
|
| `syncOfflineMessages / offlineMessageCount` | Offline message handling |
|
|
| `ImClient` | Low-level STOMP client |
|
|
| `ImDatabase` | WatermelonDB wrapper |
|
|
| `uploadFile` | File upload for IM |
|
|
|
|
**Additional peer dependency:** `@nozbe/watermelondb >= 0.27.0`
|
|
|
|
---
|
|
|
|
### @xuqm/rn-push
|
|
|
|
Multi-vendor push registration. Automatically detects the device vendor (Huawei, Xiaomi, OPPO, vivo, Honor, FCM, APNS) and bridges to the native push module.
|
|
|
|
| Export | Description |
|
|
|--------|-------------|
|
|
| `PushSDK.initialize(userId?)` | Initialize push and register device token |
|
|
| `PushSDK.registerToken(userId, token, vendor?)` | Register a push token with server |
|
|
| `PushSDK.unregisterToken(userId)` | Unregister push token |
|
|
| `PushSDK.setDeviceToken(token, vendor?)` | Manually set device token |
|
|
| `PushSDK.onPushToken(callback)` | Listen for push token updates |
|
|
| `PushSDK.logout(userId?)` | Unregister and clean up |
|
|
| `isNativePushAvailable()` | Check if native push module is linked |
|
|
| `detectVendorNative()` | Detect vendor via native module |
|
|
| `registerPushNative()` | Trigger native vendor registration |
|
|
|
|
**Native module:** Requires `NativeModules.XuqmPushModule` to be linked in the host app.
|
|
|
|
---
|
|
|
|
### @xuqm/rn-update
|
|
|
|
App update check and RN plugin (bundle) hot-update. Checks for new app versions and downloads/caches RN bundles for OTA delivery.
|
|
|
|
| Export | Description |
|
|
|--------|-------------|
|
|
| `UpdateSDK.registerPlugin(meta)` | Register plugin metadata at bundle load time |
|
|
| `UpdateSDK.checkAppUpdate(bypassIgnore?)` | Check for app-level update |
|
|
| `UpdateSDK.openStore(url?, marketUrl?)` | Open app store page |
|
|
| `UpdateSDK.checkPluginUpdate(moduleId)` | Check if a plugin bundle has an update |
|
|
| `UpdateSDK.downloadPluginBundle(url)` | Download bundle source text |
|
|
| `UpdateSDK.cachePluginBundle(id, ver, md5, src)` | Cache bundle to AsyncStorage |
|
|
| `UpdateSDK.getCachedPluginBundle(id)` | Read cached bundle |
|
|
| `UpdateSDK.checkAndCachePlugin(id)` | One-step check + download + cache |
|
|
| `UpdateSDK.getRegisteredPlugins()` | List all registered plugins |
|
|
| `UpdateSDK.getAppVersionCode / getAppVersionName` | Get host app version |
|
|
|
|
**Types:** `PluginMeta`, `AppUpdateInfo`, `PluginUpdateInfo`, `CachedRnBundle`
|
|
|
|
---
|
|
|
|
### @xuqm/rn-xwebview
|
|
|
|
Enhanced WebView with JSBridge for bidirectional communication between RN and web content. Includes progress bar, inline view, and full-screen screen components.
|
|
|
|
| Export | Description |
|
|
|--------|-------------|
|
|
| `XWebViewScreen` | Full-screen WebView (React Navigation screen) |
|
|
| `XWebViewView` | Inline WebView component |
|
|
| `XWebViewProgress` | Progress bar component |
|
|
| `openXWebView(url, options?)` | Open WebView programmatically |
|
|
| `setXWebViewController(controller)` | Set global WebView controller |
|
|
| `getXWebViewConfig()` | Get current WebView config |
|
|
|
|
**Additional dependencies:** `react-native-webview`, `react-native-blob-util`, `react-native-svg`
|
|
|
|
**Additional peer dependency:** `@react-navigation/native >= 7.0.0`
|
|
|
|
---
|
|
|
|
## Development
|
|
|
|
### Prerequisites
|
|
|
|
- Node.js >= 18
|
|
- Yarn (workspaces)
|
|
- React Native development environment
|
|
|
|
### Commands
|
|
|
|
```bash
|
|
# Type-check all packages
|
|
yarn typecheck
|
|
|
|
# Type-check a single package
|
|
cd packages/im && yarn typecheck
|
|
```
|
|
|
|
### Publishing
|
|
|
|
Packages are published to the private npm registry at `https://nexus.xuqinmin.com/repository/npm-hosted/`.
|
|
|
|
```bash
|
|
# Publish a single package
|
|
cd packages/common
|
|
npm publish
|
|
|
|
# Publish all packages (from each package directory)
|
|
for pkg in common im push update xwebview; do
|
|
cd packages/$pkg && npm publish && cd ../..
|
|
done
|
|
```
|
|
|
|
### Project layout
|
|
|
|
```
|
|
packages/<name>/
|
|
├── src/
|
|
│ └── index.ts # Public API
|
|
├── package.json
|
|
├── tsconfig.json
|
|
└── README.md
|
|
```
|
|
|
|
Each package has its own `package.json`, `tsconfig.json`, and `publishConfig` pointing to the hosted registry. The root `package.json` is a private meta-package that depends on all sub-packages.
|
|
|
|
---
|
|
|
|
## Plugin Scaffolding
|
|
|
|
The `create-plugin.mjs` script generates a new UpdateSDK plugin skeleton and auto-registers it into the host project.
|
|
|
|
### Usage
|
|
|
|
```bash
|
|
# Interactive mode
|
|
node packages/update/scripts/create-plugin.mjs
|
|
|
|
# CLI mode
|
|
node packages/update/scripts/create-plugin.mjs <moduleId> [title] [subtitle] [accentColor]
|
|
```
|
|
|
|
### What it generates
|
|
|
|
- `bundle.ts` -- Plugin entry point
|
|
- `{PascalCase}Screen.tsx` -- Screen component
|
|
- `plugin.json` -- Plugin metadata
|
|
|
|
### What it auto-registers
|
|
|
|
- `pluginCatalog.ts` -- Adds plugin to catalog
|
|
- `debugPlugins.ts` -- Adds to debug plugin list
|
|
- `package.json` -- Adds build script for the new bundle
|
|
- `metro.split.config.js` -- Adds bundle entry
|
|
- `babel.config.js` -- Adds module alias
|
|
- `tsconfig.json` -- Adds path mapping
|
|
|
|
**Module ID rules:** Lowercase alphanumeric, must be unique across all plugins.
|