即时通信 IM Android&iOS&Windows&Mac(搜索消息)

消息云端搜索,提升 App 使用体验必备功能,可以帮助用户从纷繁复杂的信息中直接找到预期内容,快捷方便;也可以作为运营工具,增加相关内容的引导,简洁高效。

相关产品
即时通信 IM 产品页,含版本规格、价格与购买入口。

一、功能描述

注意:说明:

二、消息搜索参数类

消息搜索参数类为 V2TIMMessageSearchParam(Android / iOS & Mac / Windows)。搜索消息时,SDK 会按照该对象的设置,执行不同的搜索逻辑。

V2TIMMessageSearchParam 的参数说明如下:

参数 含义 说明
keywordList 关键字列表 最多支持 5 个。当消息发送者以及消息类型均未指定时,必须设置关键字列表;否则,关键字列表可以为空。
keywordListMatchType 指定关键字列表匹配类型 可设置为 “或” 关系搜索,或 “与” 关系搜索。取值分别为 V2TIM_KEYWORD_LIST_MATCH_TYPE_OR 和 V2TIM_KEYWORD_LIST_MATCH_TYPE_AND。默认为 “或” 关系搜索。
senderUserIDList 指定 userID 发送的消息 最多支持 5 个。
messageTypeList 指定搜索的消息类型集合 传空表示搜索支持的全部类型消息(V2TIMFaceElem 和 V2TIMGroupTipsElem 不支持搜索)。其他类型取值参考 V2TIMElemType(Android / iOS & Mac / Windows)。
conversationID 搜索 “全部会话” 还是搜索 “指定的会话” conversationID 为空,搜索全部会话;conversationID 不为空,搜索指定会话。
searchTimePosition 搜索的起始时间点 默认为 0(从现在开始搜索)。UTC 时间戳,单位:秒。
searchTimePeriod 从起始时间点开始的过去时间范围 默认为 0(不限制时间范围)。24 x 60 x 60 代表过去一天,单位:秒。
searchCount 搜索的数量 搜索的数量,最大支持100。
searchCursor 搜索的游标 搜索的起始位置,第一次填写空字符串,续拉时填写上一次返回的 V2TIMMessageSearchResult 中的 searchCursor。

三、消息搜索结果类

消息搜索结果类为 V2TIMMessageSearchResult(Android / iOS & Mac / Windows)。参数说明如下:

参数 含义 说明
totalCount 搜索结果总数 如果搜索指定会话,返回满足搜索条件的消息总数。如果搜索全部会话,返回满足搜索条件的消息所在的所有会话总数量。
messageSearchResultItems 搜索结果列表 如果搜索指定会话,返回结果列表只包含该会话结果;如果搜索全部会话,会对满足搜索条件的消息根据会话 ID 分组,分页返回分组结果。
searchCursor 续拉的游标 调用搜索接口续拉时需要填的游标

其中 messageSearchResultItems 是个列表,内含 V2TIMMessageSearchResultItem(Android / iOS & Mac / Windows)对象,参数说明如下:

参数 含义 说明
conversationID 会话 ID –
messageCount 消息数量 当前会话一共搜索到了多少条符合要求的消息。
messageList 满足搜索条件的消息列表 如果搜索指定会话,messageList 中装载的是本会话中所有满足搜索条件的消息列表。如果搜索全部会话,messageList 中装载的消息条数会有如下两种可能:如果某个会话中匹配到的消息条数 > 1,则 messageList 为空,你可以在 UI 上显示 “{messageCount} 条相关记录”。如果某个会话中匹配到的消息条数 = 1,则 messageList 为匹配到的那条消息,你可以在 UI 上显示之,并高亮匹配关键词。

四、搜索全部会话的消息

当用户在搜索框输入关键字搜索消息时,你可以调用 searchCloudMessages(Android / iOS & Mac / Windows)搜索消息。

如果你希望在全部会话范围内搜索,只需要将 V2TIMMessageSearchParam 中的 conversationID 设置为空或者不设置即可。

示例代码如下:

AndroidiOS & MacWindowsList<String> keywordList = new ArrayList<>();keywordList.add("abc");keywordList.add("123");V2TIMMessageSearchParam searchParam = new V2TIMMessageSearchParam();// 设置搜索关键字searchParam.setKeywordList(keywordList);// 搜索20条数据searchParam.setSearchCount(20);// 从最新的会话开始搜索searchParam.setSearchCursor("");// 从当前时间开始搜索searchParam.setSearchTimePosition(0);// 搜索10分钟之内的消息searchParam.setSearchTimePeriod(600);V2TIMManager.getMessageManager().searchCloudMessages(searchParam, newV2TIMValueCallback<V2TIMMessageSearchResult>() { @Override public void onSuccess(V2TIMMessageSearchResult v2TIMMessageSearchResult) { // 搜索成功 } @Override public void onError(int code, String desc) { // 搜索失败 }});V2TIMMessageSearchParam *param = [[V2TIMMessageSearchParam alloc] init];// 设置搜索关键字param.keywordList = @[@"abc", @"123"];param.messageTypeList = nil;param.conversationID = nil;param.searchTimePosition = 0;param.searchTimePeriod = 0;// 搜索20条数据param.searchCount = 20;// 从最新的会话开始搜索param.searchCursor = @"";[V2TIMManager.sharedInstance searchCloudMessages:param succ:^(V2TIMMessageSearchResult *searchResult) { // 搜索成功,searchResult 中返回搜索结果} fail:^(int code, NSString *desc) { // 搜索失败}];template <class T>class ValueCallback final : public V2TIMValueCallback<T> {public: using SuccessCallback = std::function<void(const T&)>; using ErrorCallback = std::function<void(int, const V2TIMString&)>; ValueCallback() = default; ~ValueCallback() override = default; void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) { success_callback_ = std::move(success_callback); error_callback_ = std::move(error_callback); } void OnSuccess(const T& value) override { if (success_callback_) { success_callback_(value); } } void OnError(int error_code, const V2TIMString& error_message) override { if (error_callback_) { error_callback_(error_code, error_message); } }private: SuccessCallback success_callback_; ErrorCallback error_callback_;};V2TIMMessageSearchParam searchParam;// 设置搜索关键字searchParam.keywordList.PushBack("abc");searchParam.keywordList.PushBack("123");// 搜索20条数据searchParam.searchCount = 20;// 从最新的会话开始搜索searchParam.searchCursor = "";auto callback = new ValueCallback<V2TIMMessageSearchResult>{};callback->SetCallback( [=](const V2TIMMessageSearchResult& messageSearchResult) { // 搜索成功 delete callback; }, [=](int error_code, const V2TIMString& error_message) { // 搜索失败 delete callback; });V2TIMManager::GetInstance()->GetMessageManager()->SearchCloudMessages(searchParam, callback);

五、搜索指定会话的消息

当用户在搜索框输入关键字搜索消息时,你可以调用 searchCloudMessages(Android / iOS & Mac / Windows)搜索消息。

示例代码如下:

AndroidiOS & MacWindowsList<String> keywordList = new ArrayList<>();keywordList.add("abc");keywordList.add("123");V2TIMMessageSearchParam searchParam = new V2TIMMessageSearchParam();// 搜索与用户 user1 的单聊消息searchParam.setConversationID("c2c_user1");// 设置搜索关键字searchParam.setKeywordList(keywordList);// 搜索20条数据searchParam.setSearchCount(20);// 从最新的会话开始搜索searchParam.setSearchCursor("");// 从当前时间开始搜索searchParam.setSearchTimePosition(0);// 搜索10分钟之内的消息searchParam.setSearchTimePeriod(600);V2TIMManager.getMessageManager().searchCloudMessages(searchParam, newV2TIMValueCallback<V2TIMMessageSearchResult>() { @Override public void onSuccess(V2TIMMessageSearchResult v2TIMMessageSearchResult) { // 搜索成功 } @Override public void onError(int code, String desc) { // 搜索失败 }});V2TIMMessageSearchParam *param = [[V2TIMMessageSearchParam alloc] init];// 设置搜索关键字param.keywordList = @[@"abc", @"123"];param.messageTypeList = nil;// 搜索与用户 user1 的单聊消息param.conversationID = @"c2c_user1";param.searchTimePosition = 0;param.searchTimePeriod = 0;// 搜索20条数据param.searchCount = 20;// 从最新的会话开始搜索param.searchCursor = @"";[V2TIMManager.sharedInstance searchCloudMessages:param succ:^(V2TIMMessageSearchResult *searchResult) { // 搜索成功,searchResult 中返回搜索结果} fail:^(int code, NSString *desc) { // 搜索失败}];template <class T>class ValueCallback final : public V2TIMValueCallback<T> {public: using SuccessCallback = std::function<void(const T&)>; using ErrorCallback = std::function<void(int, const V2TIMString&)>; ValueCallback() = default; ~ValueCallback() override = default; void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) { success_callback_ = std::move(success_callback); error_callback_ = std::move(error_callback); } void OnSuccess(const T& value) override { if (success_callback_) { success_callback_(value); } } void OnError(int error_code, const V2TIMString& error_message) override { if (error_callback_) { error_callback_(error_code, error_message); } }private: SuccessCallback success_callback_; ErrorCallback error_callback_;};V2TIMMessageSearchParam searchParam;// 搜索与用户 user1 的单聊消息searchParam.conversationID = "c2c_user1";// 设置搜索关键字searchParam.keywordList.PushBack("abc");searchParam.keywordList.PushBack("123");// 搜索20条数据searchParam.searchCount = 20;// 从最新的会话开始搜索searchParam.searchCursor = "";auto callback = new ValueCallback<V2TIMMessageSearchResult>{};callback->SetCallback( [=](const V2TIMMessageSearchResult& messageSearchResult) { // 搜索成功 delete callback; }, [=](int error_code, const V2TIMString& error_message) { // 搜索失败 delete callback; });V2TIMManager::GetInstance()->GetMessageManager()->SearchCloudMessages(searchParam, callback);

六、搜索典型场景示例

普通的 IM 聊天软件,搜索界面的展示通常分这几种场景:

图 1:搜索聊天记录 图 2:搜索更多聊天记录 图 3:搜索指定会话的消息
  

下文我们将依次向你展示如何利用 IM SDK 的搜索 API 实现上图的典型场景。

七、展示最近几个活跃的会话

如图 1 所示,最下方是搜索到的消息所属的最近 3 个会话列表,实现方式如下:

1. 设置搜索参数 V2TIMMessageSearchParam

·conversationID 设置为 null,表示搜索所有会话的消息。

·searchCursor 设置为 "",表示搜索最新的数据。

·searchCount 设置为 3,表示返回最近的会话数量,UI 上一般显示 3 条。

2. 处理搜索回调结果 V2TIMMessageSearchResult

·totalCount 表示匹配到的消息所属的所有会话数量。

·messageSearchResultItems 列表为最近 3(即入参 searchCount)个会话信息。其中元素 V2TIMMessageSearchResultItem 的 messageCount 表示当前会话搜索到的消息总数量;

·搜索到的消息条数 > 1,则 messageList 为空,你可以在 UI 上显示 “4 条相关聊天记录”,其中的 4 为 messageCount。

·搜索到的消息条数 = 1,则 messageList 为匹配到的那条消息,你可以在 UI 上显示消息内容并高亮搜索关键词,例如搜索典型场景示例图中的 “test”。

示例代码如下:

AndroidiOS & MacWindowsList<String> keywordList = new ArrayList<>();keywordList.add("test");V2TIMMessageSearchParam v2TIMMessageSearchParam = new V2TIMMessageSearchParam();// conversationID 设置为 null 表示搜索所有会话中的消息,结果会按照会话分类v2TIMMessageSearchParam.setConversationID(null);v2TIMMessageSearchParam.setKeywordList(keywordList);v2TIMMessageSearchParam.setSearchCursor("");v2TIMMessageSearchParam.setSearchCount(3);V2TIMManager.getMessageManager().searchCloudMessages(v2TIMMessageSearchParam, new V2TIMValueCallback<V2TIMMessageSearchResult>() { @Override public void onSuccess(V2TIMMessageSearchResult v2TIMMessageSearchResult) { // 匹配到的消息所属的所有会话数量 int totalCount = v2TIMMessageSearchResult.getTotalCount(); // 最近3个根据消息会话分类的信息 List<V2TIMMessageSearchResultItem> resultItemList = v2TIMMessageSearchResult.getMessageSearchResultItems(); for (V2TIMMessageSearchResultItem resultItem : resultItemList) { // 会话 ID String conversationID = resultItem.getConversationID(); // 该会话匹配到的所有消息数量 int totalMessageCount = resultItem.getMessageCount(); // 消息列表:如果 totalMessageCount > 1,该列表为空;如果 totalMessageCount = 1,该列表元素为此消息 List<V2TIMMessage> v2TIMMessageList = resultItem.getMessageList(); } } @Override public void onError(int code, String desc) { }});V2TIMMessageSearchParam *param = [[V2TIMMessageSearchParam alloc] init];param.keywordList = @[@"test"];// conversationID 设置为 nil 表示搜索所有会话中的消息,结果会按照会话分类param.conversationID = nil;param.searchCursor = @"";param.searchCount = 3;[V2TIMManager.sharedInstance searchCloudMessages:param succ:^(V2TIMMessageSearchResult *searchResult) {// 匹配到的消息所属的所有会话数量 NSInteger totalCount = searchResult.totalCount; // 最近3个根据消息会话分类的信息 NSArray<V2TIMMessageSearchResultItem *> *messageSearchResultItems = searchResult.messageSearchResultItems; for (V2TIMMessageSearchResultItem *searchItem in messageSearchResultItems) { // 会话 ID NSString *conversationID = searchItem.conversationID; // 该会话匹配到的所有消息数量 NSUInteger messageCount = searchItem.messageCount; // 消息列表 NSArray<V2TIMMessage *> *messageList = searchItem.messageList ?: @[]; }} fail:^(int code, NSString *desc) { // fail}];template <class T>class ValueCallback final : public V2TIMValueCallback<T> {public: using SuccessCallback = std::function<void(const T&)>; using ErrorCallback = std::function<void(int, const V2TIMString&)>; ValueCallback() = default; ~ValueCallback() override = default; void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) { success_callback_ = std::move(success_callback); error_callback_ = std::move(error_callback); } void OnSuccess(const T& value) override { if (success_callback_) { success_callback_(value); } } void OnError(int error_code, const V2TIMString& error_message) override { if (error_callback_) { error_callback_(error_code, error_message); } }private: SuccessCallback success_callback_; ErrorCallback error_callback_;};V2TIMMessageSearchParam searchParam;// conversationID 设置为空表示搜索所有会话中的消息,结果会按照会话分类searchParam.conversationID = "";searchParam.keywordList.PushBack("test");searchParam.searchCursor = "";searchParam.searchCount = 3;auto callback = new ValueCallback<V2TIMMessageSearchResult>{};callback->SetCallback( [=](const V2TIMMessageSearchResult& messageSearchResult) { // 匹配到的消息所属的所有会话数量 uint32_t totalCount = messageSearchResult.totalCount; // 最近3个根据消息会话分类的信息 V2TIMMessageSearchResultItemVector messageSearchResultItems = messageSearchResult.messageSearchResultItems; for (size_t i = 0; i < messageSearchResultItems.Size(); ++i) { // 会话 ID V2TIMString conversationID = messageSearchResultItems[i].conversationID; // 该会话匹配到的所有消息数量 uint32_t messageCount = messageSearchResultItems[i].messageCount; // 消息列表:如果 messageCount > 1,该列表为空;如果 messageCount = 1,该列表元素为此消息 V2TIMMessageVector messageList = messageSearchResultItems[i].messageList; } delete callback; }, [=](int error_code, const V2TIMString& error_message) { // 搜索失败 delete callback; });V2TIMManager::GetInstance()->GetMessageManager()->SearchCloudMessages(searchParam, callback);

八、展示所有搜索到的消息所属会话列表

点击搜索典型场景示例图 1 中的 “更多聊天记录”,会跳转到图 2,展示所有搜索到的消息所属的会话列表。搜索参数和搜索结果描述跟上文的场景类似。

为了防止内存膨胀,我们强烈建议你分页加载会话列表。

举个例子,分页加载,每页展示 10 条会话结果,搜索参数 V2TIMMessageSearchParam 可以参考如下设置:

1. 首次调用:设置参数 searchCount = 10,searchCursor = ""。调用 searchCloudMessages 获取消息搜索结果,解析并展示到首页,并且从结果回调中获取会话总数量 totalCount 以及下次请求的游标 searchCursor。

2. 当界面滑动快到底部后根据上一次请求结果中的游标 searchCursor 继续拉取下一页的数据 。

示例代码如下:

AndroidiOS & MacWindows……// 记录搜索游标String searchCursor = "";……private void searchConversation(String cursor) { List<String> keywordList = new ArrayList<>(); keywordList.add("test"); V2TIMMessageSearchParam v2TIMMessageSearchParam = new V2TIMMessageSearchParam(); v2TIMMessageSearchParam.setConversationID(null); v2TIMMessageSearchParam.setKeywordList(keywordList); v2TIMMessageSearchParam.setSearchCount(10); v2TIMMessageSearchParam.setSearchCursor(cursor); V2TIMManager.getMessageManager().searchCloudMessages(v2TIMMessageSearchParam, newV2TIMValueCallback<V2TIMMessageSearchResult>() { @Override public void onSuccess(V2TIMMessageSearchResult v2TIMMessageSearchResult) { // 匹配到的消息所属的所有会话数量 int totalCount = v2TIMMessageSearchResult.getTotalCount(); // 下一页的游标 searchCursor = v2TIMMessageSearchResult.getSearchCursor(); // 该页的根据消息会话分类的信息 List<V2TIMMessageSearchResultItem> resultItemList = v2TIMMessageSearchResult.getMessageSearchResultItems(); for (V2TIMMessageSearchResultItem resultItem : resultItemList) { // 会话 ID String conversationID = resultItem.getConversationID(); // 该会话匹配到的所有消息数量 int totalMessageCount = resultItem.getMessageCount(); // 消息列表:如果 totalMessageCount > 1,该列表为空;如果 totalMessageCount = 1,该列表元素为此消息 List<V2TIMMessage> v2TIMMessageList = resultItem.getMessageList(); } } @Override public void onError(int code, String desc) {} });}// 当需要加载下一页时public void loadMore() { searchConversation(searchCursor);}……// 记录搜索游标NSString *searchCursor = @"";……- (void)searchConversation:(NSString *)cursor { V2TIMMessageSearchParam *param = [[V2TIMMessageSearchParam alloc] init]; param.keywordList = @[@"test"]; param.conversationID = nil; param.searchCursor = cursor; param.searchCount = 10; [V2TIMManager.sharedInstance searchCloudMessages:param succ:^(V2TIMMessageSearchResult *searchResult) { // 匹配到的消息所属的所有会话数量 NSUInteger totalCount = searchResult.totalCount; // 下一页的游标 searchCursor = searchResult.searchCursor; // 该页的根据消息会话分类的信息 NSArray<V2TIMMessageSearchResultItem *> *messageSearchResultItems = searchResult.messageSearchResultItems; for (V2TIMMessageSearchResultItem *searchItem in messageSearchResultItems) { // 会话 ID NSString *conversationID = searchItem.conversationID; // 该会话匹配到的所有消息数量 NSUInteger totalMessageCount = searchItem.messageCount; // 消息列表:如果 totalMessageCount > 1,该列表为空;如果 totalMessageCount = 1,该列表元素为此消息 NSArray<V2TIMMessage *> *messageList = searchItem.messageList ?: @[]; } } fail:^(int code, NSString *desc) { // fail }];}// 当需要加载下一页时- (void)loadMore { [self searchConversation:searchCursor];}template <class T>class ValueCallback final : public V2TIMValueCallback<T> {public: using SuccessCallback = std::function<void(const T&)>; using ErrorCallback = std::function<void(int, const V2TIMString&)>; ValueCallback() = default; ~ValueCallback() override = default; void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) { success_callback_ = std::move(success_callback); error_callback_ = std::move(error_callback); } void OnSuccess(const T& value) override { if (success_callback_) { success_callback_(value); } } void OnError(int error_code, const V2TIMString& error_message) override { if (error_callback_) { error_callback_(error_code, error_message); } }private: SuccessCallback success_callback_; ErrorCallback error_callback_;};// 记录搜索游标V2TIMString searchCursor = "";void SearchConversation(V2TIMString cursor) { V2TIMMessageSearchParam searchParam; searchParam.keywordList.PushBack("test"); searchParam.searchCursor = cursor; searchParam.searchCount = 10; auto callback = new ValueCallback<V2TIMMessageSearchResult>{}; callback->SetCallback( [=](const V2TIMMessageSearchResult& messageSearchResult) { // 匹配到的消息所属的所有会话数量 uint32_t totalCount = messageSearchResult.totalCount; // 下一页的游标 searchCursor = messageSearchResult.searchCursor; // 该页的根据消息会话分类的信息 V2TIMMessageSearchResultItemVector messageSearchResultItems = messageSearchResult.messageSearchResultItems; for (size_t i = 0; i < messageSearchResultItems.Size(); ++i) { // 会话 ID V2TIMString conversationID = messageSearchResultItems[i].conversationID; // 该会话匹配到的所有消息数量 uint32_t messageCount = messageSearchResultItems[i].messageCount; // 消息列表:如果 messageCount > 1,该列表为空;如果 messageCount = 1,该列表元素为此消息 V2TIMMessageVector messageList = messageSearchResultItems[i].messageList; } delete callback; }, [=](int error_code, const V2TIMString& error_message) { // 搜索失败 delete callback; }); V2TIMManager::GetInstance()->GetMessageManager()->SearchLocalMessages(searchParam, callback);}// 当需要加载下一页时void LoadMore() { SearchConversation(searchCursor); }

九、展示搜索指定会话的消息

与 搜索典型场景示例 图 2 展示会话列表不同的是,图 3 所示在指定会话中搜索到的消息列表。

为了防止内存膨胀,我们强烈建议你分页加载消息。举个例子,分页加载,每页展示 10 条消息结果:

1. 搜索参数 V2TIMMessageSearchParam 可以参考如下设置:

·设置搜索参数 V2TIMMessageSearchParam 的 conversationID 为搜索的会话 ID。

·首次调用:设置参数 searchCount = 10,searchCursor = ""。调用 searchCloudMessages 获取消息搜索结果,解析并展示到首页,并且从结果回调中获取会话总数量 totalCount 以及下一页的游标 searchCursor。

·再次调用:更新参数 searchCursor 的值为上一步调用结果中的返回值。

2. 处理搜索结果 V2TIMMessageSearchResult:

·totalCount 表示该会话匹配到的所有消息数量。

·messageSearchResultItems 列表只有该会话的结果。列表中的元素 V2TIMMessageSearchResultItem 的 messageCount 为该分页的消息数量,messageList 为该分页的消息列表。

·searchCursor 表示下一页搜索的起始游标。

示例代码如下:

AndroidiOS & MacWindows……// 记录搜索游标String searchCursor = "";……private void searchMessage(String cursor) { List<String> keywordList = new ArrayList<>(); keywordList.add("test"); V2TIMMessageSearchParam v2TIMMessageSearchParam = new V2TIMMessageSearchParam(); v2TIMMessageSearchParam.setConversationID(conversationID); v2TIMMessageSearchParam.setKeywordList(keywordList); v2TIMMessageSearchParam.setSearchCount(10); v2TIMMessageSearchParam.setSearcuCursor(cursor); V2TIMManager.getMessageManager().searchCloudMessages(v2TIMMessageSearchParam, newV2TIMValueCallback<V2TIMMessageSearchResult>() { @Override public void onSuccess(V2TIMMessageSearchResult v2TIMMessageSearchResult) { // 该会话匹配到的所有消息数量 int totalMessageCount = v2TIMMessageSearchResult.getTotalCount(); // 下一页的游标 searchCursor = v2TIMMessageSearchResult.getSearchCursor(); // 该页消息信息 List<V2TIMMessageSearchResultItem> resultItemList = v2TIMMessageSearchResult.getMessageSearchResultItems(); for (V2TIMMessageSearchResultItem resultItem : resultItemList) { // 会话 ID String conversationID = resultItem.getConversationID(); // 该页的消息数量 int totalMessageCount = resultItem.getMessageCount(); // 该页的消息数据列表 List<V2TIMMessage> v2TIMMessageList = resultItem.getMessageList(); } } @Override public void onError(int code, String desc) { } });}// 当需要加载下一页时public void loadMore() { searchMessage(searchCursor);}……// 记录搜索游标NSString *searchCursor = @"";……- (void)searchMessage:(NSString *)cursor { V2TIMMessageSearchParam *param = [[V2TIMMessageSearchParam alloc] init]; param.keywordList = @[@"test"]; // conversationID 是要搜索的会话 ID param.conversationID = conversationID; param.searchCursor = cursor; param.searchCount = 10; [V2TIMManager.sharedInstance searchCloudMessages:param succ:^(V2TIMMessageSearchResult *searchResult) { // 该会话匹配到的所有消息数量 NSUInteger totalMessageCount = searchResult.totalCount; // 下一页的游标 searchCursor = searchResult.searchCursor; // 该页消息信息 NSArray<V2TIMMessageSearchResultItem *> *messageSearchResultItems = searchResult.messageSearchResultItems; for (V2TIMMessageSearchResultItem *searchItem in messageSearchResultItems) { // 会话 ID NSString *conversationID = searchItem.conversationID; // 该页的消息数量 NSUInteger totalMessageCount = searchItem.messageCount; // 该页的消息数据列表 NSArray<V2TIMMessage *> *messageList = searchItem.messageList ?: @[]; } } fail:^(int code, NSString *desc) { // fail }];}// 当需要加载下一页时- (void)loadMore { [self searchMessage:searchCursor];}template <class T>class ValueCallback final : public V2TIMValueCallback<T> {public: using SuccessCallback = std::function<void(const T&)>; using ErrorCallback = std::function<void(int, const V2TIMString&)>; ValueCallback() = default; ~ValueCallback() override = default; void SetCallback(SuccessCallback success_callback, ErrorCallback error_callback) { success_callback_ = std::move(success_callback); error_callback_ = std::move(error_callback); } void OnSuccess(const T& value) override { if (success_callback_) { success_callback_(value); } } void OnError(int error_code, const V2TIMString& error_message) override { if (error_callback_) { error_callback_(error_code, error_message); } }private: SuccessCallback success_callback_; ErrorCallback error_callback_;};// 记录搜索游标V2TIMString searchCursor = "";void SearchConversation(V2TIMString cursor) { V2TIMMessageSearchParam searchParam; searchParam.conversationID = conversationID; searchParam.keywordList.PushBack("test"); searchParam.searchCursor = cursor; searchParam.searchCount = 10; auto callback = new ValueCallback<V2TIMMessageSearchResult>{}; callback->SetCallback( [=](const V2TIMMessageSearchResult& messageSearchResult) { // 该会话匹配到的所有消息数量 uint32_t totalCount = messageSearchResult.totalCount; // 下一页的游标 searchCursor = messageSearchResult.searchCursor; // 该页消息信息 V2TIMMessageSearchResultItemVector messageSearchResultItems = messageSearchResult.messageSearchResultItems; for (size_t i = 0; i < messageSearchResultItems.Size(); ++i) { // 会话 ID V2TIMString conversationID = messageSearchResultItems[i].conversationID; // 该页的消息数量 uint32_t messageCount = messageSearchResultItems[i].messageCount; // 该页的消息数据列表 V2TIMMessageVector messageList = messageSearchResultItems[i].messageList; } delete callback; }, [=](int error_code, const V2TIMString& error_message) { // 搜索失败 delete callback; }); V2TIMManager::GetInstance()->GetMessageManager()->SearchCloudMessages(searchParam, callback);}// 当需要加载下一页时void LoadMore() { SearchConversation(SearchCursor); }

十、搜索自定义消息

通常情况下,如果你使用接口 createCustomMessage(data)(Android / iOS & Mac / Windows)创建自定义消息,该消息无法被搜到,因为 SDK 将该自定义消息保存为二进制数据流。

如果你希望自定义消息可以被搜到,需要使用接口 createCustomMessage(data, description, extension)(Android / iOS & Mac / Windows)来创建并发送自定义消息,把需要搜索的文本放到 description 参数中。

如果你配置了离线推送功能,设置参数 description 后,自定义消息也会有离线推送且通知栏展示该参数内容。

如果不需要离线推送可以用发消息接口 sendMessage(Android / iOS & Mac / Windows)的参数 V2TIMOfflinePushInfo 中的 disablePush 来控制。

如果推送的通知栏内容不想展示为被搜索的文本,可以用参数 V2TIMOfflinePushInfo 中的 desc 来另外设置推送内容。

十一、搜索富媒体消息

富媒体消息包含文件、图片、语音、视频消息。

对于文件消息,界面通常显示文件名。如果调用 createFileMessage 创建文件消息时传入 fileName 参数,fileName 会作为文件消息被搜索的内容,与搜索关键词进行匹配。如果未设置 fileName,SDK 则会自动从 filePath 提取文件名作为搜索内容。

fileName 和 filePath 信息会保存到本地和服务器,换设备拉取相关信息后均可搜索。

对于图片、语音、视频消息,并没有类似 fileName 这种名称,界面通常显示缩略图或时长,此时指定 keywordList 搜索无效。

如果你希望搜索出此类消息,可以指定 messageTypeList 为 V2TIM_ELEM_TYPE_IMAGE/V2TIM_ELEM_TYPE_SOUND/V2TIM_ELEM_TYPE_VIDEO 做分类搜索,此时会搜索出所有指定类型的消息。

赞 (0)
上一篇 4天前
下一篇 4天前