主题
媒体与离线 API
1. 推荐的媒体发送接口
| api-id | 用途 | 必要元数据 | 返回 |
|---|---|---|---|
media.send_image | 发送图片 | 本地文件、MIME、宽、高 | XHIMMediaTask |
media.send_video | 发送视频 | 本地文件、MIME、时长、宽、高 | XHIMMediaTask |
media.send_audio | 发送音频 | 本地文件、MIME、时长、可选 waveform | XHIMMediaTask |
media.send_file | 发送文件 | 本地文件、MIME、展示文件名 | XHIMMediaTask |
这些便利接口先计算内容哈希,再把上传任务和依赖消息意图一起持久化给 Core。 成功返回表示“任务已可靠接受”,随后即使 App 重启,Core 仍可按策略继续分片、 审核、提交对象和入队消息。
平台入口:
- iOS:
client.sendImage/sendVideo/sendAudio/sendFile; - macOS:
client.sendImage/sendVideo/sendAudio/sendFile; - Android:
client.sendImage/sendVideo/sendAudio/sendFile的File重载; - Windows:
XHIMMediaMessaging.SendImageAsync/...; - HarmonyOS:
XHIMMediaMessaging.sendImage/...。
直接传入 uploader 的旧重载只为兼容早期版本,已经弃用。新接入不要自行先上传 到临时 URL 再组装消息。
2. durable media task
| api-id | 用途 | 主要输入 | 返回 |
|---|---|---|---|
media.accept_upload | 接受一个完整上传意图 | XHIMMediaUploadIntent | XHIMMediaTask |
media.accept_download | 接受一个下载/缓存意图 | XHIMMediaDownloadIntent | XHIMMediaTask |
media.get_task | 查询任务快照 | taskID | XHIMMediaTask |
media.cancel_task | 取消持久化媒体工作流 | taskID | XHIMMediaTask |
cancelMediaTask 和“取消等待某次 API”不是一回事:
- 取消 Swift Task / Coroutine / CancellationToken / requestId,只停止当前调用;
cancelMediaTask(taskID)会改变持久化业务任务状态,并阻止依赖消息继续提交。
XHIMMediaTask.state:
text
pending → authorizing → transferring → verifying → completed
↕ paused └──────→ failed
任意未终态 ────────────────────────────────→ cancelled未知 native state 必须保留 task ID 并稍后重查,不能强行映射为 failed。 messageEnqueued == true 表示媒体引用已经进入依赖消息;最终消息投递状态仍从消息 查询判断。
3. 媒体缓存读取
media.open_cache
输入 cacheKey,返回 XHIMMediaCacheReader。Reader 公开:
| api-id / 操作 | iOS | macOS | Android | Windows | HarmonyOS |
|---|---|---|---|---|---|
| 大小 | byteSize | byteSize | byteSize | ByteSize | byteSize |
media.cache_read 读取范围 | read(offset:length:) | read(offset:length:) | read(offset,length) | ReadAsync(offset,length) | read(offset,length) |
media.cache_chunks 分块消费 | chunks(...) | chunks(...) | chunks(...) | ReadChunksAsync(...) | stream(...) |
media.cache_close 关闭 | close() | close() | close() | DisposeAsync() | close() |
Reader 读取 SDK 管理的缓存对象,不暴露数据库路径、对象存储密钥或临时下载 凭证。读取结束后必须显式关闭。UI 播放器需要随机读时保持一个 Reader,不要每帧 重新打开。
4. 媒体消息模型
XHIMMediaMessageFactory 提供:
| api-id | 工厂 |
|---|---|
media.factory_image | image / Windows Image |
media.factory_audio | audio / Windows Audio |
media.factory_video | video / Windows Video |
media.factory_file | file / Windows File |
生成的仍是 XHIMOutgoingMessage,可直接交给 sendMessage。媒体 payload 只包含 XHIMMediaRef 和展示元数据:
mediaIDcontentHashSHA256byteSizemimeTypestorageRevision- 可选
XHIMMediaEncryption
永远不要把本地文件路径、系统相册 URI、管理员密钥或即将过期的 signed URL 写入消息 payload。
5. 系统 Picker 的职责
SDK UI Kit 提供相机、相册、视频、录音和文件入口,但系统权限及 Picker 仍属于 宿主 App:
- 用户在宿主页面触发 Picker;
- 宿主取得有权限的本地文件/URI;
- 调用媒体便利接口;
- 立即释放临时系统授权,长期任务由 SDK Core 接管;
- 订阅
mediaTaskUpdated更新进度和失败态。
购买方可以替换 Picker 与 UI,不需要修改 Core。
6. 离线只读 Reader
当后台扩展、通知扩展、桌面快速搜索或受限进程不允许启动网络 Client 时,使用 XHIMOfflineReader。它只打开同一账号的加密本地投影,不启动登录、WebSocket、 同步或 Outbox。
| api-id | 用途 | 输入 | 返回 |
|---|---|---|---|
offline.open | 打开只读数据库 | storage、App ID、数据库 Key Provider | XHIMOfflineReader |
offline.messages | 会话消息分页 | conversation、cursor、limit | XHIMMessagePage |
offline.search_messages | 本地消息搜索 | query、cursor、limit | XHIMMessagePage |
offline.conversations | 会话分页 | cursor、limit | XHIMConversationPage |
offline.friend_requests | 好友申请分页 | cursor、limit | XHIMSocialPage |
offline.friendships | 好友分页 | cursor、limit | XHIMSocialPage |
offline.groups | 群组分页 | cursor、limit | XHIMSocialPage |
offline.group_members | 群成员分页 | conversation、cursor、limit | XHIMSocialPage |
offline.blocks | 黑名单分页 | cursor、limit | XHIMSocialPage |
offline.group_join_requests | 入群申请分页 | cursor、limit | XHIMSocialPage |
offline.close | 关闭 Reader | 无 | Void |
离线 Reader 与在线 Client 共享模型,但不保证读取瞬间包含刚到达服务器的数据。 需要最新状态时回到主 App,由在线 Client 完成同步后再查。
7. 数据库 Key
Reader 的 Key Provider 必须从平台安全存储读取当前账号数据库 Key:
- iOS Keychain;
- macOS Keychain;
- Android Keystore 包装后的 Key;
- Windows DPAPI / Credential Locker;
- HarmonyOS HUKS。
不要把 Key 写进源码、UserDefaults、SharedPreferences、注册表明文或普通配置 文件。Key 错误时 Reader 应失败关闭,不能退回明文 SQLite。