消息概览
了解 OpenIM iOS SDK 的消息创建、发送、接收与本地存储模型。
OpenIM iOS SDK 的消息能力围绕 OIMMessageInfo 展开。普通消息以及由本地文件创建的媒体消息,使用 OIMMessageInfo 对应的类方法创建,再通过 sendMessage:recvID:groupID:isOnlineOnly:offlinePushInfo:onSuccess:onProgress:onFailure: 发送。媒体文件已经由业务侧上传并取得 URL 时,使用对应的 URL 类方法创建消息,再通过 sendMessageNotOss:recvID:groupID:offlinePushInfo:onSuccess:onFailure: 发送。两条路径都可以发送到单聊或群聊;新消息、撤回、删除、已读回执、上传进度和会话变化通过对应 listener 或 delegate 同步到应用状态。
消息页通常需要长期保存以下标识:
| 标识 | 用途 |
|---|---|
clientMsgID | 消息在客户端侧的稳定 ID,用于渲染去重、状态更新、查询和分页游标。 |
conversationID | 会话记录 ID,用于历史、搜索和未读状态;它来自会话数据,不应从数组位置推导。 |
recvID | 单聊发送目标用户 ID;发送群聊消息时传 nil。 |
groupID | 群聊发送目标群组 ID;发送单聊消息时传 nil。 |
消息类型
不同内容先通过对应的类方法生成 OIMMessageInfo。发送层统一使用 sendMessage:...,无需为每种内容维护不同发送入口。
消息类型对比
| 内容类型 | 创建方法 | 典型用途 |
|---|---|---|
| 普通文本 | createTextMessage: | 发送纯文本聊天内容。 |
| @ 文本 | createTextAtMessage:atUsersID:atUsersInfo:message: | 群聊中提醒指定成员。 |
| 图片 | createImageMessageFromFullPath: 或 createImageMessageByURL:sourcePicture:bigPicture:snapshotPicture: | 从本地文件或已上传 URL 创建图片消息。 |
| 音频 | createSoundMessage:duration: 或 createSoundMessageByURL:duration:size: | 创建语音或音频消息。 |
| 视频 | createVideoMessage:videoType:duration:snapshotPath: 或 URL 版本 | 创建视频与快照消息。 |
| 文件 | createFileMessage:fileName: 或 createFileMessageByURL:fileName:size: | 创建普通附件。 |
| 自定义消息 | createCustomMessage:extension:description: | 承载卡片、邀请、订单等结构化业务数据。 |
| Markdown | OpenIMCore Open_im_sdkCreateMarkdownMessage | 创建 Markdown 文本消息;高阶 OIMMessageInfo 没有对应 factory selector。 |
本地媒体由 SDK 上传时使用路径创建方法与 sendMessage:...;业务已经取得远端 URL 时,使用对应 URL 创建方法与 sendMessageNotOss:...,避免再次进入内置上传链路。需要共享的业务数据放入消息内容;只影响当前设备展示的状态写入 localEx。
OIMMessageInfo 常用属性
固定 SDK 中用于路由、渲染和状态合并的常用属性如下:
| 属性 | 类型 | 说明 |
|---|---|---|
clientMsgID | NSString * _Nullable | 客户端消息 ID;非空时作为消息稳定合并标识。 |
serverMsgID | NSString * _Nullable | 服务端消息 ID,不替代本地合并所用的 clientMsgID。 |
sessionType | OIMConversationType | 单聊或群聊会话类型,用于解析消息所属会话。 |
sendID | NSString * _Nullable | 发送者用户 ID;单聊中需结合当前用户判断对端。 |
recvID | NSString * _Nullable | 接收者用户 ID;当前用户发送单聊消息时用于确定对端。 |
groupID | NSString * _Nullable | 群聊所属群组 ID。 |
contentType | OIMMessageContentType | 消息内容类型 enum,决定使用哪个内容元素渲染。 |
sendTime | NSTimeInterval | 消息发送时间,用于排序,不能作为消息唯一标识。 |
status | OIMMessageStatus | 消息发送状态 enum。 |
isRead | BOOL | SDK 当前记录的已读状态。 |
textElem、pictureElem、soundElem、videoElem、fileElem、atTextElem、customElem 等内容属性都可以为 nil。渲染时应同时检查 contentType 与对应 element;缺少预期内容时使用降级占位,不要强制取值。
消息处理流程
- 使用
createTextMessage:、createImageMessageFromFullPath:等类方法创建本地OIMMessageInfo。 - 使用
sendMessage:recvID:groupID:isOnlineOnly:offlinePushInfo:onSuccess:onProgress:onFailure:发送。 - 发送端在成功回调中按
clientMsgID合并最终消息;接收端通过OIMAdvancedMsgListener接收增量。 - 进入聊天页时使用历史查询建立快照,再持续合并消息、撤回、删除与已读回执事件。
消息创建方法只在内存中创建对象,不会发送消息,也不会触发接收事件。发送成功、远端收到事件与重新查询历史是三个独立阶段。
会话路由
单聊发送时填写 recvID 并令 groupID 为 nil;群聊发送时填写 groupID 并令 recvID 为 nil。消息进入状态层后,以消息所属会话和 clientMsgID 去重,不要使用数组下标或显示文本作为标识。
按主题查看能力
发送消息
先创建消息,再发送到单聊或群聊。单聊填写 recvID,群聊填写 groupID,另一个目标参数传 nil。媒体文件由 SDK 上传时使用本地路径创建方法和 sendMessage:...;媒体已由业务上传时使用 URL 创建方法与 sendMessageNotOss:...。
发送成功 callback 返回值可能为空;非空时按 clientMsgID 替换本地待发送项。完整参数与错误处理见发送消息。图片、音频、视频、文件及富消息已经按类型拆分在“创建消息”菜单中。
接收消息
普通消息与只在线消息通过 OIMAdvancedMsgListener 接收。固定 iOS SDK 每次 callback 携带单个 nullable OIMMessageInfo,没有独立的离线新消息 selector;重新登录后的离线变化由 SDK 同步。应用先解析消息所属会话,再按 conversationID:clientMsgID 幂等合并。
完整接收与 listener 生命周期见接收消息。
获取消息
历史消息通过 getAdvancedHistoryMessageList:onSuccess:onFailure: 按 conversationID 和 startClientMsgID 分页读取。第一页令 startClientMsgID 为 nil,后续使用边界消息的 clientMsgID;历史结果和 delegate 增量使用同一标识去重。
搜索消息
searchLocalMessages:onSuccess:onFailure: 只搜索当前账号已同步到本地的消息。群聊搜索使用群会话的 conversationID,不是发送消息时的 groupID。
搜索流程见搜索消息。
管理消息
已发送消息可按实际能力转发、合并、删除、撤回和清理历史,也可以插入仅供本地展示的消息或发送输入状态。撤回与删除变化按 conversationID:clientMsgID 更新原气泡;完整事件只能在各自归属页注册。
相关页面包括创建转发消息、创建合并消息、修改消息、置顶或取消置顶消息、删除消息、撤回消息、插入本地单聊消息、清理全部本地消息和上报输入状态。
标记已读
markConversationMessageAsRead:onSuccess:onFailure: 清理会话未读数;单聊与群聊回执通过消息 listener 合并。调用成功只表示本次已读处理完成,不代表发送方界面或所有端状态已经更新。
单聊回执见标记会话已读;群聊成员级能力见上报群消息已读和查询群消息已读成员。
提及其他用户
群聊 @ 消息使用 createTextAtMessage:atUsersID:atUsersInfo:message: 创建,再发送到群组。atUsersID 使用稳定用户 ID,atUsersInfo 提供展示资料;接收端通过会话的 groupAtType 展示 @ 提醒。
相关流程见创建 @ 消息。
获取未读数
会话列表、总未读数和 @ 提醒来自会话 API 与 OIMConversationListener。会话层按 conversationID 合并变化,并使用最新总未读计数更新全局角标;消息页面不重复注册会话 delegate。
相关能力见维护总未读数。
自定义消息与扩展数据
需要同步给其他成员的结构化数据使用 createCustomMessage:extension:description:;只影响当前设备的附加状态使用 setMessageLocalEx:clientMsgID:localEx:onSuccess:onFailure:。本地扩展不会同步给其他端,也不会产生共享消息事件。
将音频转为文字
商业版 OpenIMCore 可以查询转写能力并把本地音频路径或 Base64 音频数据转为文字。转写结果不是 OIMSoundElem 的属性;需要只在当前设备保留时,应合并到消息既有 localEx,不要覆盖其他业务字段。
完整格式、大小、时长边界与本地保存方式见将音频转为文字。
修改与置顶消息
modifyMessageWithConversationID:message:onSuccess:onFailure: 更新指定会话中的消息内容,其他客户端通过 onMessageModified: 按 conversationID + clientMsgID 合并。setConversationPinnedMsgWithConversationID:clientMsgID:pinned:onSuccess:onFailure: 设置或取消会话消息置顶,getConversationPinnedMsgWithConversationID:onSuccess:onFailure: 建立置顶列表快照,后续通过 onChangedPinnedMsg: 更新。
完整权限、结果阶段和事件载荷见修改消息与置顶或取消置顶消息。
事件归属
消息事件按职责分散在对应能力页,概览页只说明导航和归属:新消息见接收消息,删除见批量删除消息,撤回见撤回消息,单聊已读回执见标记会话已读,群聊已读回执见上报群消息已读,输入状态见上报输入状态。会话变化的完整监听见获取会话列表。
消息创建和纯查询直接使用 callback 返回值建立对象或快照,不应描述为触发共享事件。会改变状态的调用应分别处理成功 callback、delegate 增量与重新查询校准。
消息修改、置顶会话消息和音频转写来自 enterprise SDK,并在对应页面标为商业版。当前 iOS 高阶 API 没有与 WASM 定向群消息创建完全对等的 OIMMessageInfo factory selector;不要用普通群消息或本地插入模拟该能力。
这个页面有帮助吗?