主题
二次开发扩展点
1. 自定义消息
业务消息使用稳定四元组:
text
contentType + contentVersion + payload + fallbackText推荐命名:
text
com.customer.product.order-card
com.customer.product.live-invite
com.customer.product.workflow-approval不要使用 custom1、页面类名或会随重构变化的字符串。版本只属于一个 contentType;兼容增加字段时升版本,改变业务含义时创建新类型。
swift
let outgoing = XHIMOutgoingMessage(
contentType: "com.example.shop.order-card",
contentVersion: 1,
payload: encodedOrder,
fallbackText: "[订单] ¥199.00"
)
_ = try await client.sendMessage(
conversationID: conversationID,
message: outgoing
)2. Message Plugin
XHIMMessagePlugin / Windows IXHIMMessagePlugin 定义:
| 成员 | 用途 |
|---|---|
contentType | 插件唯一负责的稳定类型 |
supportedVersions | 当前 SDK 可以解释的版本范围 |
validate | 发送前和展示前验证 payload |
presentation | 生成会话预览、通知预览和 renderer key |
XHIMMessagePluginRegistry 公开:
| api-id | iOS / macOS / Android / HarmonyOS | Windows | 说明 |
|---|---|---|---|
extension.plugin_register | register | Register | 注册;重复 contentType 失败 |
extension.plugin_unregister | unregister | Unregister | 删除注册并返回是否存在 |
extension.plugin_validate | validate | Validate | 校验 outgoing message |
extension.plugin_present | presentation | Present | 把收到的消息转为展示描述 |
Registry 放在 App 的 IM 组合根中只创建一次。不要让每个 Cell 注册插件,也不要 在 Plugin 中发网络请求。
未知类型或未知版本的规则固定:
- 保留完整
XHIMMessage; - 展示
fallbackText; - 不执行未知 payload;
- 升级后可重新渲染已有历史消息。
3. 内置标准消息工厂
XHIMStandardMessageFactory:
| api-id / 工厂 | 内容 |
|---|---|
extension.standard_sticker — sticker / Sticker | 表情包 ID、资源 URL 和描述 |
extension.standard_location — location / Location | 纬度、经度、标题和地址 |
extension.standard_contact_card — contactCard / ContactCard | 用户 ID、展示名、头像 |
extension.standard_quote — quote / Quote | 被引用消息身份、发送者和摘要 |
extension.standard_mention — mention / Mention | 文本、用户 ID 列表、是否 @所有人 |
extension.standard_merged_forward — mergedForward / MergedForward | 标题和不可变 XHIMForwardItem 列表 |
XHIMMentionContent.decode(Windows Decode)可以从收到的 Message 解码 @ 信息,并用 mentions(userID) 判断是否命中当前用户。
这些工厂只负责消息 envelope,不授予位置、通讯录或相册权限;系统权限由宿主 App 明确请求。
4. Renderer
UI Kit 的 Renderer Registry 以 rendererKey 或 contentType 选择消息 Cell / Composable / WPF DataTemplate / ArkUI Component。
Renderer 输入只依赖:
XHIMMessage- Plugin 给出的
XHIMMessagePresentation - 主题与宿主路由闭包
Renderer 不直接调用 C ABI、不读取 SQLite、不持有 Token。点击订单卡片、名片 或位置时,通过宿主注入的路由闭包回到购买方业务模块。
各端入口:
| 平台 | UI/Renderer 入口 |
|---|---|
| iOS | XHIMSwiftUI 的 message renderer registry 和 SwiftUI View |
| macOS | XHIMSwiftUI Renderer;AppKit 可使用 NSHostingView |
| Android | xhim-ui-compose 的 message renderer registry / Composable |
| Windows | XHIM.UI.Wpf.XHIMMessageRendererRegistry |
| HarmonyOS | XHIMMessageRendererRegistry / XHIMMessageItemRenderer |
5. UI Kit 可替换边界
text
App Navigation / Theme / Business Screens
└── XHIM UI Kit(可选)
├── Conversation List
├── Chat Timeline + Composer
├── Attachment Picker
└── Message Renderer Registry
└── Headless XHIMClient购买方可以:
- 替换导航、主题、字体、颜色和本地化;
- 只使用会话列表或聊天页的一部分;
- 完全不用 UI Kit,自己用 Facade 构建 MVVM/VIP 页面;
- 注册业务消息 Renderer;
- 替换相机、相册、文件和录音入口;
- 注入用户头像、业务页面路由和权限提示。
购买方不需要、也不应修改:
- XHIM Core 二进制;
xhim_v1C ABI;- SDK 数据库 schema;
- Outbox、同步和媒体 durable task 状态机;
- Endpoint 验签和凭证轮换逻辑。
6. Attachment Picker
UI 包提供的 Picker 是薄适配层:
| 能力 | iOS | macOS | Android | Windows | HarmonyOS |
|---|---|---|---|---|---|
| 拍照/视频 | AVFoundation / UIImagePicker | AVFoundation | Activity Result / Camera | 宿主相机服务 | 系统 Picker |
| 相册 | PhotosPicker | PhotosPicker / NSOpenPanel | Photo Picker | FileOpenPicker | PhotoViewPicker |
| 文件 | UIDocumentPicker | NSOpenPanel + 安全作用域 | Storage Access Framework | FileOpenPicker | DocumentViewPicker |
| 录音 | AVAudioRecorder | AVAudioRecorder | MediaRecorder | 宿主录音服务 | AVRecorder |
Picker 返回本地受权资源后,统一交给 durable media API,而不是把路径塞入消息。
7. Repository 与 ViewModel
推荐每个登录账号创建一个组合根:
text
XHIMService
├── XHIMClient
├── MessagePluginRegistry
├── ConversationRepository
├── MessageRepository
├── SocialRepository
└── MediaRepositoryRepository 的读模型来自 SDK Query API;事件只触发重新查询。ViewModel 只消费 Repository 状态并调用业务动作。这样二次开发可以替换 UI,而不会把连接、同步、 事件和 Token 逻辑散落在页面里。
8. 扩展兼容清单
发布新的自定义消息前至少验证:
- 当前版本正常收发和渲染;
- 旧版本只显示 fallback,不崩溃;
- iOS/macOS/Android/Windows/HarmonyOS payload 字节一致;
- Push 通知预览不泄露敏感字段;
- 合并转发和引用只保存必要快照;
- 内容审核能根据 contentType 路由;
- Renderer 失败时回退到普通未知消息气泡;
- 消息复制、搜索、清空、撤回和离线 Reader 不破坏未知 payload。