浏览 SDKs · iOS
SDKsiOS

消息概览

了解 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:承载卡片、邀请、订单等结构化业务数据。
MarkdownOpenIMCore Open_im_sdkCreateMarkdownMessage创建 Markdown 文本消息;高阶 OIMMessageInfo 没有对应 factory selector。

本地媒体由 SDK 上传时使用路径创建方法与 sendMessage:...;业务已经取得远端 URL 时,使用对应 URL 创建方法与 sendMessageNotOss:...,避免再次进入内置上传链路。需要共享的业务数据放入消息内容;只影响当前设备展示的状态写入 localEx

OIMMessageInfo 常用属性

固定 SDK 中用于路由、渲染和状态合并的常用属性如下:

属性类型说明
clientMsgIDNSString * _Nullable客户端消息 ID;非空时作为消息稳定合并标识。
serverMsgIDNSString * _Nullable服务端消息 ID,不替代本地合并所用的 clientMsgID
sessionTypeOIMConversationType单聊或群聊会话类型,用于解析消息所属会话。
sendIDNSString * _Nullable发送者用户 ID;单聊中需结合当前用户判断对端。
recvIDNSString * _Nullable接收者用户 ID;当前用户发送单聊消息时用于确定对端。
groupIDNSString * _Nullable群聊所属群组 ID。
contentTypeOIMMessageContentType消息内容类型 enum,决定使用哪个内容元素渲染。
sendTimeNSTimeInterval消息发送时间,用于排序,不能作为消息唯一标识。
statusOIMMessageStatus消息发送状态 enum。
isReadBOOLSDK 当前记录的已读状态。

textElempictureElemsoundElemvideoElemfileElematTextElemcustomElem 等内容属性都可以为 nil。渲染时应同时检查 contentType 与对应 element;缺少预期内容时使用降级占位,不要强制取值。

消息处理流程

  1. 使用 createTextMessage:createImageMessageFromFullPath: 等类方法创建本地 OIMMessageInfo
  2. 使用 sendMessage:recvID:groupID:isOnlineOnly:offlinePushInfo:onSuccess:onProgress:onFailure: 发送。
  3. 发送端在成功回调中按 clientMsgID 合并最终消息;接收端通过 OIMAdvancedMsgListener 接收增量。
  4. 进入聊天页时使用历史查询建立快照,再持续合并消息、撤回、删除与已读回执事件。

消息创建方法只在内存中创建对象,不会发送消息,也不会触发接收事件。发送成功、远端收到事件与重新查询历史是三个独立阶段。

会话路由

单聊发送时填写 recvID 并令 groupIDnil;群聊发送时填写 groupID 并令 recvIDnil。消息进入状态层后,以消息所属会话和 clientMsgID 去重,不要使用数组下标或显示文本作为标识。

按主题查看能力

发送消息

先创建消息,再发送到单聊或群聊。单聊填写 recvID,群聊填写 groupID,另一个目标参数传 nil。媒体文件由 SDK 上传时使用本地路径创建方法和 sendMessage:...;媒体已由业务上传时使用 URL 创建方法与 sendMessageNotOss:...

发送成功 callback 返回值可能为空;非空时按 clientMsgID 替换本地待发送项。完整参数与错误处理见发送消息。图片、音频、视频、文件及富消息已经按类型拆分在“创建消息”菜单中。

接收消息

普通消息与只在线消息通过 OIMAdvancedMsgListener 接收。固定 iOS SDK 每次 callback 携带单个 nullable OIMMessageInfo,没有独立的离线新消息 selector;重新登录后的离线变化由 SDK 同步。应用先解析消息所属会话,再按 conversationID:clientMsgID 幂等合并。

完整接收与 listener 生命周期见接收消息

获取消息

历史消息通过 getAdvancedHistoryMessageList:onSuccess:onFailure:conversationIDstartClientMsgID 分页读取。第一页令 startClientMsgIDnil,后续使用边界消息的 clientMsgID;历史结果和 delegate 增量使用同一标识去重。

读取列表见加载历史消息,定位单条消息见按 ID 查找消息

搜索消息

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;不要用普通群消息或本地插入模拟该能力。