获取历史消息
获取历史消息时,您可以选择仅从本地数据中获取、仅从远端获取或 者同时从本地与远端获取。
从 5.38.0 开始,如果返回的消息携带引用关系信息,应用可从返回的 RCMessage 对象的 quoteInfo 属性中读取。消息本身仍保持原消息类型,例如图片回复仍是图片消息,语音回复仍是语音消息。旧版引用消息仍通过 RCReferenceMessage(RC:ReferenceMsg)消息体返回。
开通服务
从远端获取单群聊历史消息是指从融云服务端获取历史消息,该功能要求 App Key 已启用融云提供的单群聊消息云端存储服务。您可以在控制台 IM 服务的服务购买页面为当前使用的 App Key 开启服务。如果使用生产环境的 App Key,请注意仅 IM 旗舰版或 IM 尊享版可开通该服务。具体功能与费用以融云官方价格说明页面及计费说明文档为准。
请注意区分历史消息记录与离线消息?。融云针对单聊、群聊、系统消息默认提供最多 7 天(可调整)的离线消息缓存服务。客户端上线时 SDK 会自动收取离线期间的消息,无需 App 层调用 API。详见管理离线消息存储配置。
从本地数据库中获取消息
您可以通过 getHistoryMessages 方法分页查询指定会话存储在本地数据库中的历史消息,并获取到异步返回的消息对象列表。列表中的消息按发送时间从新到旧排列。
IMLib SDK 从 5.3.0 版本开始支持异步获取消息列表,如果您版本低于 5.3.0 或者需要同步获取消息列表,可以在 IMLib SDK 查找使用 getHistoryMessages 的同名方法即可。
获取会话中指定消息 messageId 前的消息
接口原型
- (void)getHistoryMessages:(RCConversationType)conversationType
targetId:(NSString *)targetId
oldestMessageId:(long)oldestMessageId
count:(int)count
completion:(nullable void(^)(NSArray<RCMessage *> *_Nullable messages))completion;
参数说明
count 参数表示返回列表中应包含多少消息。oldestMessageId 参数用于控制分页的边界。每次调用 getHistoryMessages 方法时,SDK 会以 oldestMessageId 参数指向的消息为界,继续在下一页返回指定数量的消息。如果需要获取会话中最新的 count 条消息,可以将 oldestMessageId 设置为 -1。
建议您通过获取返回结果中最早一条消息的 messageId,并在下一次调用时作为 oldestMessageId 传入,以便遍历整个会话的消息历史记录。
| 参数 | 类型 | 说明 |
|---|---|---|
| conversationType | RCConversationType | 会话类型 |
| targetId | NSString | 会话 Id |
| oldestMessageId | long | 用于控制分页的边界,以此 messageId 为界,获取发送时间更小的 count 条消息。设置为 -1 或 0,表示获取最新的 count 条消息。 |
| count | int | 需要获取的消息数量,按照消息发送时间从新到旧排列 |
| completion | Block | 异步回调,返回获取到的消息实体 RCMessage 数组 |
示例代码
[[RCCoreClient sharedCoreClient] getHistoryMessages:ConversationType_PRIVATE
targetId:@"targetId"
oldestMessageId:-1
count:10
completion:^(NSArray<RCMessage *> * _Nullable messages) {
}];
获取指定时间戳前后的消息
异步获取会话中指定 时间戳之前之后、指定数量的最新消息实体,并返回消息实体 RCMessage 对象列表。
接口原型
- (void)getHistoryMessages:(RCConversationType)conversationType
targetId:(NSString *)targetId
sentTime:(long long)sentTime
beforeCount:(int)beforeCount
afterCount:(int)afterCount
completion:(nullable void(^)(NSArray<RCMessage *> * _Nullable messages))completion;
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| conversationType | RCConversationType | 会话类型 |
| targetId | NSString | 会话 ID |
| sentTime | long long | 以此时间戳为界,获取早于或晚于该时间的消息。 |
| beforeCount | int | 需要获取的发送 时间早于指定时间戳的消息数量。 |
| afterCount | int | 需要获取的发送时间晚于指定时间戳的消息数量。 |
| completion | Block | 获取的消息的回调。 |
示例代码
[[RCCoreClient sharedCoreClient] getHistoryMessages:ConversationType_PRIVATE
targetId:@"targetId"
sentTime:0
beforeCount:10
afterCount:10 completion:^(NSArray<RCMessage *> * _Nullable messages) {
}];
获取会话中指定消息类型的消息
接口原型
- (void)getHistoryMessages:(RCConversationType)conversationType
targetId:(NSString *)targetId
objectName:(nullable NSString *)objectName
oldestMessageId:(long)oldestMessageId
count:(int)count
completion:(nullable void(^)(NSArray<RCMessage *> *_Nullable messages))completion;
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| conversationType | RCConversationType | 会话类型。 |
| targetId | NSString | 会话 ID。 |
| objectName | NSString | 消息类型标识,内置消息类型的标识可参见消息类型概述。 |
| oldestMessageId | long | 用于控制分页的边界,以此 messageId 为界,获取发送时间更小的 count 条消息。设置为 -1 或 0,表示获取最新的 count 条消息。 |
| count | int | 需要获取的消息数量,按照消息发送时间从新到旧排列 |
| completion | Block | 异步回调,返回获取到的消息实体 RCMessage 数组 |
示例代码
[[RCCoreClient sharedCoreClient] getHistoryMessages:ConversationType_PRIVATE
targetId:@"targetId"
objectName:@"RC:TxtMsg"
oldestMessageId:-1
count:10
completion:^(NSArray<RCMessage *> * _Nullable messages) {
}];
如果需要获取早于或晚于指定消息的历史消息,可以使用以下带 isForward 参数的方法:
方法原型
- (void)getHistoryMessages:(RCConversationType)conversationType
targetId:(NSString *)targetId
objectName:(nullable NSString *)objectName
baseMessageId:(long)baseMessageId
isForward:(BOOL)isForward
count:(int)count
completion:(nullable void(^)(NSArray<RCMessage *> *_Nullable messages))completion;
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| conversationType | RCConversationType | 会话类型。 |
| targetId | NSString | 会话 ID。 |
| objectName | NSString | 消息类型标识,内置消息类型的标识可参见消息类型概述。 |
| baseMessageId | long | 用于控制分页的边界,以此 messageId 为界,获取发送时间更小的 count 条消息。设置为 -1 或 0,表示获取最新的 count 条消息。 |
| isForward | BOOL | 查询 方向,true 为向前,false 为向后。 |
| count | int | 需要获取的消息数量,按照消息发送时间从新到旧排列。 |
| completion | Block | 异步回调,返回获取到的消息实体 RCMessage 数组。 |
示例代码
[[RCCoreClient sharedCoreClient] getHistoryMessages:ConversationType_PRIVATE
targetId:@"targetId"
objectName:@"RC:TxtMsg"
baseMessageId:-1
isForward:true
count:10
completion:^(NSArray<RCMessage *> * _Nullable messages) {
}];
通过消息 messageUId 获取消息
- SDK 从 5.2.5.1 版本开始支持通过消息的 messageUId 批量获取消 息的接口。仅在
RCChannelClient类中提供。支持的会话类型包括单聊、群聊、聊天室、超级群。 - 如果 SDK 版本低于 5.2.5.1,可以使用
RCCoreClient类中的getMessageByUId方法,该方法一次仅支持传入一个 messageUId。
消息的 messageUId 是由融云服务端生成的消息的全局唯一 ID。消息存入本地数据库后,您可以通过消息的 messageUId,从本地数据库中获取到该消息。
例如,您的用户希望收藏聊天记录中的部分消息,App 可以先记录消息的 messageUId,在需要展示时调用 getBatchLocalMessages,传入收藏消息的 messageUId,从本地数据库中提取消息。
接口原型
- (void)getBatchLocalMessages:(RCConversationType)conversationType
targetId:(NSString *)targetId
channelId:(nullable NSString *)channelId
messageUIDs:(NSArray<NSString *> *)messageUIDs
success:(nullable void (^)(NSArray<RCMessage *> *messages, NSArray<NSString *> *mismatch))successBlock
error:(nullable void (^)(RCErrorCode status))errorBlock;
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| conversationType | RCConversationType | 会话类型,支持单聊、群聊、聊天室、超级群。 |
| targetId | NSString | 会话 ID |
| channelId | NSString | 超级群的频道 ID。非超级群会话类型时,传入 null。 |
| messageUIDs | NSArray | 消息的 messageUId,即由融云服务端生成的全局唯一 ID。必须传入有效的 messageUId,最多支持 20 条。 |
| successBlock | Block | 成功回调。返回结果中包含消息对象列表和提取失败的消息的 messageUId 列表。 |
| errorBlock | Block | 失败回调。 |
示例代码
[[RCChannelClient sharedChannelManager] getBatchLocalMessages:conversationType_PRIVATE
targetId: @"targetId"
channelId: nil
messageUIDs:@[@"C3GC-8VAA-LJQ4-TPPM", @"B5GC-3VAA-LJQ4-TXXA"]
success:^(NSArray<RCMessage *> *messages, NSArray<NSString *> *mismatch) {
}
error:^(RCErrorCode status) {
}];
- 要获取的消息需要是本地数据库中已存有的消息。
- 单次仅可从一个会话(
targetId)或超级群频道(channelId)中提取消息。 - 超级群会话默认只同步会话最后一条消息。如果您直接调用该方法(例如您传入了通过融云服务端回调全量消息路由获取的 messageUId),可能 IMLib SDK 无法在本地找到对应消息。建议先调用
getBatchRemoteUltraGroupMessages从服务端获取消息。 - 聊天室会话会在用户退出聊天室后自动清空本地消息。如果用户退出聊天室后再调用该接口,则无法取得本地消息。
按消息 UID 批量查询本地与远端消息
SDK 从 5.38.0 版本开始支持通过 RCCoreClient 按消息 UID 批量查询本地与远端消息。
getMessagesByUIds 会先查询本地数据库;如果部分消息未在本地命中,SDK 会继续从服务端查询未命中的消息,并将服务端返回的消息写入本地数据库。
接口原型
- (void)getMessagesByUIds:(RCGetMessagesByUIdsParams *)params
success:(nullable void (^)(NSArray<RCMessageResult *> *results))successBlock
error:(nullable void (^)(RCErrorCode status))errorBlock;
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| params | RCGetMessagesByUIdsParams | 查询参数对象。 |
| successBlock | Block | 获取成功的回调,返回按请求 UID 对应的查询结果。 |
| errorBlock | Block | 获取失败的回调,返回 RCErrorCode 错误码。 |
RCGetMessagesByUIdsParams 参数说明:
| 参数 | 类型 | 说明 |
|---|---|---|
| conversationIdentifier | RCConversationIdentifier | 会话标识,需要指定会话类型和会话 ID。超级群会话还需要指定频道 ID。 |
| messageUIds | NSArray<NSString *> | 消息的 messageUId 数组,必须传入有效值,数量范围为 1 到 20 个。 |
RCMessageResult 返回结果说明:
| 参数 | 类型 | 说明 |
|---|---|---|
| messageUId | NSString | 本次查询的消息 messageUId。 |
| message | RCMessage | 查询到的消息实体。未查询到或查询失败时可能为空。 |
| code | RCErrorCode | 当前 messageUId 对应的查询结果错误码。 |
示例代码
RCConversationIdentifier *identifier =
[[RCConversationIdentifier alloc] initWithConversationIdentifier:ConversationType_PRIVATE
targetId:@"targetId"];
RCGetMessagesByUIdsParams *params = [[RCGetMessagesByUIdsParams alloc] init];
params.conversationIdentifier = identifier;
params.messageUIds = @[@"C3GC-8VAA-LJQ4-TPPM", @"B5GC-3VAA-LJQ4-TXXA"];
[[RCCoreClient sharedCoreClient] getMessagesByUIds:params
success:^(NSArray<RCMessageResult *> *results) {
for (RCMessageResult *result in results) {
if (result.code == RC_SUCCESS && result.message) {
RCMessage *message = result.message;
// 处理查询到的消息
} else {
// 处理未查询到或查询失败的消息
}
}
} error:^(RCErrorCode status) {
// 处理接口调用失败
}];
- 单次仅可查询同一个会话或同一个超级群频道中的消息。
messageUIds数量必须在 1 到 20 个之间。- 超级群会话需要在
conversationIdentifier中传入channelId。 - 如果本地和服务端都未查询到消息,或远端查询失败,您可以通过对应
RCMessageResult的code判断该条消息的查询结果。
批量获取带原始 JSON 数据的消息
- 从
5.40.0版本开始,IMLib SDK 支持通过RCCoreClient高性能批量获取原始消息。 - 该接口适用于批量读取消息原始 JSON 数据的场景。SDK 不会将消息内容反序列化为具体的消息类型对象,返回结果中的
RCMessage.content均为RCMessageContent基类,原始消息内容保存在content.rawJSONData中。 - 该接口不支持聊天室和超级群会话类型。
接口原型
- (void)batchFetchOriginalMessage:(RCConversationIdentifier *)conversationIdentifier
timestamp:(int64_t)timestamp
count:(int32_t)count
success:(nullable void (^)(NSArray<RCMessage *> *messages))successBlock
error:(nullable void (^)(RCErrorCode status))errorBlock;
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| conversationIdentifier | RCConversationIdentifier | 会话标识,需要指定会话类型和会话 ID。 |
| timestamp | int64_t | 分页查询的消息发送时间戳 sentTime。传 0 表示从最新消息开始获取。 |
| count | int32_t | 需要获取的消息数量,取值范围为 1 到 500。 |
| successBlock | Block | 获取成功回调,返回 RCMessage 数组。 |
| errorBlock | Block | 获取失败回调,返回错误码。 |
如果需要读取消息原始 JSON,可从返回的 message.content.rawJSONData 中获取。读取前请判断返回值是否为空;为空时,可按业务需要跳过该消息或降级处理。
示例代码
RCConversationIdentifier *identifier =
[[RCConversationIdentifier alloc] initWithConversationIdentifier:ConversationType_PRIVATE
targetId:@"targetId"];
[[RCCoreClient sharedCoreClient] batchFetchOriginalMessage:identifier
timestamp:0
count:20
success:^(NSArray<RCMessage *> *messages) {
for (RCMessage *message in messages) {
NSData *rawJSONData = message.content.rawJSONData;
if (rawJSONData.length == 0) {
continue;
}
NSString *rawJSONString =
[[NSString alloc] initWithData:rawJSONData encoding:NSUTF8StringEncoding];
// 处理原始 JSON 字符串 rawJSONString
}
}
error:^(RCErrorCode status) {
}];
获取远端历史消息
您可以使用 getRemoteHistoryMessages 方法直接查询指定会话存储在单群聊消息云端存储中的历史消息。
获取会话的远端历史消息
IMLib SDK 可以按照指定条件直接查询并获取单群聊消息云端存储中的满足查询条件的远端历史消息。查询结果与本地数据库对比,排除重复的消息后,返回消息对象列表。返回的消息列表中的消息按发送时间从新到旧排列。
- 因为默认该接口返回的消息会跟本地消息排重后返回,建议先使用
getHistoryMessages获取所有在本地数据库消息后,再以最后一条本地消息的 sentTime 作为 recordTime 获取远端历史消息。此方式无法获取断档消息,如果想获取断档消息,请使用getMessages接口获取本地与远端历史消息.
- (void)getRemoteHistoryMessages:(RCConversationType)conversationType
targetId:(NSString *)targetId
recordTime:(long long)recordTime
count:(int)count
success:(nullable void (^)(NSArray<RCMessage *> *messages, BOOL isRemaining))successBlock
error:(nullable void (^)(RCErrorCode status))errorBlock;
#### 参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| conversationType | RCConversationType | 会话类型 |
| targetId | NSString | 会话 ID |
| recordTime | long long | 时间戳,用于控制分页的边界,获取发送时间早于 recordTime 的历史消息。传 0 表示获取最新 count 条消息。默认值为 0。每次调用 getRemoteHistoryMessages 方法时,SDK 会以 recordTime 为界,继续在下一页返回指定数量的消息。建议获取返回结果中最早一条消息的 sentTime,并在下一次调用时作为 recordTime 的值传入,以便遍历整个会话的消息历史记录。 |
| count | int | 要获取的消息数量。如果 SDK < 5.4.1,范围为 [2-20];如果 SDK ≧ 5.4.1,范围为 [2-100]。 |
| successBlock | Block | 获取成功的回调 |
| errorBlock | Block | 获取失败的回调 |
-
success说明:回调参数 回调类型 说明 messages NSArray 获取到的历史消息数组 isRemaining BOOL 是否还有剩余消息 -
error说明:回调参数 回调类型 说明 status RCErrorCode 获取失败的错误码
示例代码
[[RCIMClient sharedRCIMClient] getRemoteHistoryMessages:ConversationType_PRIVATE
targetId:@"targetId"
recordTime:0
count:count
success:^(NSArray *messages, BOOL isRemaining) {
} error:^(RCErrorCode status) {
}];
自定义获取会话的远端历史消息
您可以通过 RCRemoteHistoryMsgOption 自定义 getRemoteHistoryMessages 方法获取远端历史消息的行为。IMLib SDK 会按照指定条件直接查询单群聊消息云端存储中的满足查询条件的历史消息。
- 因为默认
getRemoteHistoryMessages方法返回的消息会跟本地消息排重后返回,建议先使用getHistoryMessages获取所有在本地数据库消息后,再以最后一条本地消息的 sentTime 作为 recordTime 获取远端历史消息。此方式无法获取断档消息,如果想获取断档消息,请使用getMessages接口获取本地与远端历史消息.
接口原型
- (void)getRemoteHistoryMessages:(RCConversationType)conversationType
targetId:(NSString *)targetId
option:(RCRemoteHistoryMsgOption *)option
success:(nullable void (^)(NSArray<RCMessage *> *messages, BOOL isRemaining))successBlock
error:(nullable void (^)(RCErrorCode status))errorBlock;
参数说明
RCRemoteHistoryMsgOption 中包含多个配置项,其中 count 与 recordTime 参数分别是获取历史消息的数量与分页查询时间戳。order 参数用于控制获取历史消息的时间方向,可选择获取早于或者晚于给定的 recordTime 的消息。includeLocalExistMessage 参数控制返回消息列表中是否需要包含本地数据库已存在的消息。
RCRemoteHistoryMsgOption 默认按消息发送时间降序查询会话中的消息,且默认会并将查询结果与本地数据库对比,排除重复的消息后,再返回消息对象列表。在 includeLocalExistMessage 设置为 NO 的情况下,建议 App 层先使用 getHistoryMessages,在本地数据库消息全部获取完之后,再获取远端历史消息,否则可能会获取不到本地存在的消息。
如需按消息发送时间升序查询会话中的消息,建议获取返回结果中最新一条消息的 sentTime,并在下一次调用时作为 recordTime 的值传入,以便遍历整个会话的消息历史记录。升序查询消息一般可用于跳转到会话页面指定消息位置后需要查询更新的历史消息的场景。
| 参数 | 类型 | 说明 |
|---|---|---|
| conversationType | RCConversationType | 会话类型 |
| targetId | NSString | 会话 ID |
| option | RCRemoteHistoryMsgOption | 可配置的参数,包括拉取数量、拉取顺序等 |
| successBlock | Block | 获取成功的回调 |
| errorBlock | Block | 获取失败的回调 |
-
RCRemoteHistoryMsgOption说明:参数 说明 recordTime 时间戳,用于控制分页查询消息的边界。默认值为 0。count 要获取的消息数量。如果 SDK < 5.4.1,范围为 [2-20];如果 SDK ≧ 5.4.1,范围为 [2-100];默认值为 0,表示不获取。order 拉取顺序。 RCRemoteHistoryOrderDesc:降序,按消息发送时间递减的顺序,获取发送时间早于recordTime的消息,返回的列表中的消息按发送时间从新到旧排列。RCRemoteHistoryOrderAsc:升序,按消息发送时间递增的顺序,获取发送时间晚于recordTime的消息,返回的列表中的消息按发送时间从旧到新排列。默认值为RCRemoteHistoryOrderDesc。includeLocalExistMessage 是否包含本地数据库中的已有消息。 YES:包含,查询结果不与本地数据库排除重复,直接返回从服务端获取的历史消息。NO:不包含,查询结果先与本地数据库排除重复,只返回本地数据库中不存在的消息。默认值为NO。 -
success说明:回调参数 回调类型 说明 messages NSArray 获取到的历史消息数组 isRemaining BOOL 是否还有剩余消息 -
error说明:回调参数 回调类型 说明 status RCErrorCode 获取失败的错误码
示例代码
RCRemoteHistoryMsgOption *option = [RCRemoteHistoryMsgOption new];
option.recordTime = recordTime;
option.count = 10;
option.order = RCRemoteHistoryOrderDesc;
option.includeLocalExistMessage = NO;
[[RCIMClient sharedRCIMClient] getRemoteHistoryMessages:ConversationType_PRIVATE targetId:@"targetId" option:option success:^(NSArray *messages, BOOL isRemaining) {
} error:^(RCErrorCode status) {
}];
获取本地与远端历史消息
getMessages 方法与 getRemoteHistoryMessages 的区别是 getMessages 会先查询指定会话存储本地数据库的消息,当本地消息无法满 足查询条件时,再查询在单群聊消息云端存储中的历史消息,以返回连续且相邻的消息对象列表。
您可以通过 getMessages 的 RCHistoryMessageOption 配置,自定义 getMessages 方法获取远端历史消息的行为:
接口原型
- (void)getMessages:(RCConversationType)conversationType
targetId:(NSString *)targetId
option:(RCHistoryMessageOption *)option
complete:(nullable void (^)(NSArray <RCMessage *> * _Nullable messages,long long timestamp, BOOL isRemaining, RCErrorCode code))complete
error:(nullable void (^)(RCErrorCode status))errorBlock;
参数说明
RCHistoryMessageOption 中包含多个配置项,count 参数表示返回列表中应包含多少消息。recordTime 参数用于控制分页的边界。每次调用 getMessages 方法时,SDK 会以 recordTime 为界,继续在下一页返回指定数量的消息。如果需要获取会话中最新的 count 条消息,可以将 recordTime 设置为 0。Order 参数用于控制获取历史消息的时间方向,可选择获取早于或者晚于给定的 recordTime 的消息。
RCHistoryMessageOption 默认降序查询会话中的消息,建议获取返回结果中最早一条消息的 sentTime,并在下一次调用时作为 recordTime 的值传入,以便遍历整个会话的消息历史记录。升序查询消息一般可用于跳转到会话页面指定消息位置后需要查询更新的历史消息的场景。
| 参数 | 类型 | 说明 |
|---|---|---|
| conversationType | RCConversationType | 会话类型 |
| targetId | NSString | 会话 ID |
| option | RCHistoryMessageOption | 可配置的参数,包括拉取数量、拉取顺序等 |
| complete | Block | 获取消息的回调 |
-
RCHistoryMessageOption说明:参数 说明 recordTime 时间戳,用于控制分页查询消息的边界。默认值为 0。count 要获取的消息数量。如果 SDK < 5.4.1,范围为 [2-20];如果 SDK ≧ 5.4.1,范围为 [2-100];默认值为 0,表示不获取。order 拉取顺序。 RCHistoryMessageOrderDesc:降序,按消息发送时间递减的顺序,获取发送时间早于recordTime的消息,返回的列表中的消息按发送时间从新到旧排列。RCHistoryMessageOrderAsc: 升序,按消息发送时间递增的顺序,获取发送时间晚于recordTime的消息,返回的列表中的消息按发送时间从旧到新排列。默认值为降序。
示例代码
RCHistoryMessageOption *option = [[RCHistoryMessageOption alloc] init];
option.order = RCHistoryMessageOrderDesc;
option.count = 20;
option.recordTime = message.sentTime; // 如果获取最新的 20 条消息,可以传 0。
[[RCCoreClient sharedCoreClient] getMessages:ConversationType_PRIVATE targetId:@"会话 id" option:option complete:^(NSArray *messages, RCErrorCode code) {
if (code == 0) {
// 成功
} else {
// 失败
}
}];