tencent cloud

14天试用边缘安全加速平台 EO 限时免费

Feedback

Chat

Android&iOS&Windows&Mac

Last updated: 2025-01-23 15:34:19

Search Cloud Messages

Description

Cloud message search, a must-have feature to enhance the App user experience, enables users to directly find the desired content from complex information quickly and conveniently. It can also serve as an OPS tool, facilitating efficient and concise guidance to related content.
Note:
The cloud message search feature is supported only by version 7.3.4358 or later.
This feature is a value-added feature, see Billing Overview for more information.
If this service is not activated, calling the interface will return the error code 60020.

Message Search Class

Message Search Parameter Class

The message search parameter class is V2TIMMessageSearchParam (Android/iOS & Mac/Windows). When searching for messages, the SDK will execute different search logics based on this object's settings.
The parameters of V2TIMMessageSearchParam are as follows:
Parameter
Meaning
Description
keywordList
Keyword list
It can contain up to five keywords. When the message sender and the message type are not specified, the keyword list must be set; in other cases, it can be left empty.
keywordListMatchType
Match type of the keyword list
You can set it to search with "OR" logic or "AND" logic. The values are V2TIM_KEYWORD_LIST_MATCH_TYPE_OR and V2TIM_KEYWORD_LIST_MATCH_TYPE_AND, respectively. By default, it uses "OR" logic.
senderUserIDList
Search for messages sent by a specified userID
Up to five are supported.
messageTypeList
Set of the message types to be searched for
Leaving it empty means searching for all supported types of messages (V2TIMFaceElem and V2TIMGroupTipsElem are not searchable). Refer to V2TIMElemType (Android/iOS & Mac/Windows) for other types.
conversationID
Search "all conversations" or "a specified conversation"
If conversationID is empty, search all sessions; if conversationID is not empty, search the specified session.
searchTimePosition
Start time for the search
The default is 0 (search from now). UTC Timestamp, in seconds.
searchTimePeriod
A past period of time starting from the start time
The default is 0 (unlimited time range). 24 x 60 x 60 represents the past day, in seconds.
searchCount
Number of search results
Number of searches, support up to 100.
searchCursor
Search cursor
Starting position, fill in an empty character string for the first time, and fill in the searchCursor from the last V2TIMMessageSearchResult returned for subsequent pulls.

Message Search Result Class

The message search result class is V2TIMMessageSearchResult(Android/iOS & Mac/Windows). The parameters are as described below:
Parameter
Meaning
Description
totalCount
Total number of the search result items
If a specific session is searched, the total number of messages that meet the search criteria will be returned;
If all sessions are searched, the total number of sessions containing messages that meet the search criteria will be returned.
messageSearchResultItems
Search results list
If a specific session is searched, the returned result list will only include results from that session;
If all sessions are searched, messages that meet the search criteria will be grouped by session ID, and the grouping results will be returned paginated.
searchCursor
Continue pulling the cursor
Cursor required for continuation while calling the search API
Here, messageSearchResultItems is a list containing V2TIMMessageSearchResultItem(Android/iOS & Mac/Windows) objects, with the parameters described as follows:
Parameter
Meaning
Description
conversationID
Session ID
-
messageCount
Number of messages
The total number of messages matching the criteria found in the current session.
messageList
List of messages that meet the search criteria
If a specific session is searched, messageList contains a list of all messages meeting the search criteria within this session.
If all sessions are searched, the number of messages contained in messageList may have the following two possibilities:
If the number of messages matched in a session is > 1, then messageList is empty, and you can display "{messageCount} relevant records" on the UI.
If the number of messages matched in a session = 1, then messageList is the matched message, and you can display it on the UI and highlight the search keywords.

Searching Messages in All Sessions

When a user enters keywords in the search box to search for messages, you can call searchCloudMessages(Android/iOS and Mac/Windows) to search for messages.
If you want to search within the scope of all sessions, you just need to leave conversationID in V2TIMMessageSearchParam unset or set to empty.
Below is the sample code:
Android
iOS & Mac
Windows
List<String> keywordList = new ArrayList<>();
keywordList.add("abc");
keywordList.add("123");
V2TIMMessageSearchParam searchParam = new V2TIMMessageSearchParam();
// Set the keyword for the search
searchParam.setKeywordList(keywordList);
// Search for 20 data entries
searchParam.setSearchCount(20);
// Start searching from the latest session
searchParam.setSearchCursor("");
// Start searching from the current time
searchParam.setSearchTimePosition(0);
// Search for messages within 10 minutes
searchParam.setSearchTimePeriod(600);
V2TIMManager.getMessageManager().searchCloudMessages(searchParam,newV2TIMValueCallback<V2TIMMessageSearchResult>() {
@Override
public void onSuccess(V2TIMMessageSearchResult v2TIMMessageSearchResult) {
// Data found successfully
}
@Override
public void onError(int code, String desc) {
// Failed to find the data
}
});
V2TIMMessageSearchParam *param = [[V2TIMMessageSearchParam alloc] init];
// Set the keyword for the search
param.keywordList = @[@"abc", @"123"];
param.messageTypeList = nil;
param.conversationID = nil;
param.searchTimePosition = 0;
param.searchTimePeriod = 0;
// Search for 20 data entries
param.searchCount = 20;
// Start searching from the latest session
param.searchCursor = @"";
[V2TIMManager.sharedInstance searchCloudMessages:param
succ:^(V2TIMMessageSearchResult *searchResult) {
// The search was successful, and the search results are returned in searchResult
} fail:^(int code, NSString *desc) {
// Failed to find the data
}];
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;
// Set the keyword for the search
searchParam.keywordList.PushBack("abc");
searchParam.keywordList.PushBack("123");
// Search for 20 data entries
searchParam.searchCount = 20;
// Start searching from the latest session
searchParam.searchCursor = "";

auto callback = new ValueCallback<V2TIMMessageSearchResult>{};
callback->SetCallback(
[=](const V2TIMMessageSearchResult& messageSearchResult) {
// Data found successfully
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Failed to find the data
delete callback;
});

V2TIMManager::GetInstance()->GetMessageManager()->SearchCloudMessages(searchParam, callback);

Searching for the Messages in the Specified Session

When a user enters keywords in the search box to search for messages, you can call searchCloudMessages (Android/iOS and Mac/Windows) to search for messages.
Below is the sample code:
Android
iOS & Mac
Windows
List<String> keywordList = new ArrayList<>();
keywordList.add("abc");
keywordList.add("123");
V2TIMMessageSearchParam searchParam = new V2TIMMessageSearchParam();
// Search for one-to-one messages with the 'user1' user
searchParam.setConversationID("c2c_user1");
// Set the keyword for the search
searchParam.setKeywordList(keywordList);
// Search for 20 data entries
searchParam.setSearchCount(20);
// Start searching from the latest session
searchParam.setSearchCursor("");
// Start searching from the current time
searchParam.setSearchTimePosition(0);
// Search for messages within 10 minutes
searchParam.setSearchTimePeriod(600);
V2TIMManager.getMessageManager().searchCloudMessages(searchParam,newV2TIMValueCallback<V2TIMMessageSearchResult>() {
@Override
public void onSuccess(V2TIMMessageSearchResult v2TIMMessageSearchResult) {
// Data found successfully
}
@Override
public void onError(int code, String desc) {
// Failed to find the data
}
});
V2TIMMessageSearchParam *param = [[V2TIMMessageSearchParam alloc] init];
// Set the keyword for the search
param.keywordList = @[@"abc", @"123"];
param.messageTypeList = nil;
// Search for one-to-one messages with the 'user1' user
param.conversationID = @"c2c_user1";
param.searchTimePosition = 0;
param.searchTimePeriod = 0;
// Search for 20 data entries
param.searchCount = 20;
// Start searching from the latest session
param.searchCursor = @"";
[V2TIMManager.sharedInstance searchCloudMessages:param
succ:^(V2TIMMessageSearchResult *searchResult) {
// The search was successful, and the search results are returned in searchResult
} fail:^(int code, NSString *desc) {
// Failed to find the data
}];
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;
// Search for one-to-one messages with the 'user1' user
searchParam.conversationID = "c2c_user1";
// Set the keyword for the search
searchParam.keywordList.PushBack("abc");
searchParam.keywordList.PushBack("123");
// Search for 20 data entries
searchParam.searchCount = 20;
// Start searching from the latest session
searchParam.searchCursor = "";

auto callback = new ValueCallback<V2TIMMessageSearchResult>{};
callback->SetCallback(
[=](const V2TIMMessageSearchResult& messageSearchResult) {
// Data found successfully
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Failed to find the data
delete callback;
});

V2TIMManager::GetInstance()->GetMessageManager()->SearchCloudMessages(searchParam, callback);

Typical Use Cases for the Search

In general IM chat software, a search UI is usually displayed as follows:
Figure 1. Chat Record
Figure 2. More Chat Record
Figure 3. Messages in the specified session

Loading…



Loading…



Loading…


The following describes how to implement the above use cases through IM SDK's search APIs.

Displaying the Latest Active Sessions

As shown in Figure 1, a list of the latest three sessions to which the messages found belong is displayed at the bottom. The implementation method is as follows:
1. Setting search parameters V2TIMMessageSearchParam
conversationID set to null, indicates searching messages from all sessions.
searchCursor set to "", indicates searching for the latest data.
searchCount set to 3, indicates returning the number of the most recent sessions, typically showing 3 entries on the UI.
2. Handling search callback results V2TIMMessageSearchResult
totalCount indicates the number of all sessions to which the matched messages belong.
The messageSearchResultItems list contains the last 3 sessions (as per the searchCount parameter). messageCount of V2TIMMessageSearchResultItem indicates the total number of messages found in the current session;
If the number of messages found is > 1, then messageList will be empty. You can display "4 related chat records" on the UI, where 4 represents the messageCount.
If the number of messages found = 1, then messageList is the message that matches. You can display the message content on the UI and highlight the search keyword, for example, "test" in the Typical Use Cases for the Search image.
Below is the sample code:
Android
iOS & Mac
Windows
List<String> keywordList = new ArrayList<>();
keywordList.add("test");
V2TIMMessageSearchParam v2TIMMessageSearchParam = new V2TIMMessageSearchParam();
// Setting `conversationID` to `null` is to search for messages in all sessions and the results will be classified by session
v2TIMMessageSearchParam.setConversationID(null);
v2TIMMessageSearchParam.setKeywordList(keywordList);
v2TIMMessageSearchParam.setSearchCursor("");
v2TIMMessageSearchParam.setSearchCount(3);
V2TIMManager.getMessageManager().searchCloudMessages(v2TIMMessageSearchParam, newV2TIMValueCallback<V2TIMMessageSearchResult>() {
@Override
public void onSuccess(V2TIMMessageSearchResult v2TIMMessageSearchResult) {
// Total number of matched sessions to which messages belong
int totalCount = v2TIMMessageSearchResult.getTotalCount();
// Last three messages classified by session
List<V2TIMMessageSearchResultItem> resultItemList = v2TIMMessageSearchResult.getMessageSearchResultItems();
for (V2TIMMessageSearchResultItem resultItem : resultItemList) {
// Session ID
String conversationID = resultItem.getConversationID();
// Total number of messages matching the session
int totalMessageCount = resultItem.getMessageCount();
// Message list: If totalMessageCount > 1, this list is empty; if totalMessageCount = 1, this list Element (XML) is this message
List<V2TIMMessage> v2TIMMessageList = resultItem.getMessageList();
}
}
@Override
public void onError(int code, String desc) {
}
});
V2TIMMessageSearchParam *param = [[V2TIMMessageSearchParam alloc] init];
param.keywordList = @[@"test"];
// Setting `conversationID` to `nil` is to search for messages in all sessions and the results will be classified by session
param.conversationID = nil;
param.searchCursor = @"";
param.searchCount = 3;
[V2TIMManager.sharedInstance searchCloudMessages:param succ:^(V2TIMMessageSearchResult *searchResult) {
// Total number of matched conversations to which messages belong
NSInteger totalCount = searchResult.totalCount;
// Last three messages classified by session
NSArray<V2TIMMessageSearchResultItem *> *messageSearchResultItems = searchResult.messageSearchResultItems;
for (V2TIMMessageSearchResultItem *searchItem in messageSearchResultItems) {
// Conversation ID
NSString *conversationID = searchItem.conversationID;
// Total number of messages matching the session
NSUInteger messageCount = searchItem.messageCount;
// Message list
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;
// Setting conversationID to null searches for messages in all sessions, and results will be classified by session
searchParam.conversationID = "";
searchParam.keywordList.PushBack("test");
searchParam.searchCursor = "";
searchParam.searchCount = 3;

auto callback = new ValueCallback<V2TIMMessageSearchResult>{};
callback->SetCallback(
[=](const V2TIMMessageSearchResult& messageSearchResult) {
// Total number of matched sessions to which messages belong
uint32_t totalCount = messageSearchResult.totalCount;
// Last three messages classified by session
V2TIMMessageSearchResultItemVector messageSearchResultItems =
messageSearchResult.messageSearchResultItems;
for (size_t i = 0; i < messageSearchResultItems.Size(); ++i) {
// Session ID
V2TIMString conversationID = messageSearchResultItems[i].conversationID;
// Total number of messages matching the session
uint32_t messageCount = messageSearchResultItems[i].messageCount;
// Message list: If messageCount > 1, this list is empty; if messageCount = 1, this list Element (XML) is this message
V2TIMMessageVector messageList = messageSearchResultItems[i].messageList;
}
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Failed to find the data
delete callback;
});

V2TIMManager::GetInstance()->GetMessageManager()->SearchCloudMessages(searchParam, callback);

Displaying the list of sessions to which the messages found belong

Clicking on "More chat records" in figure 1 of the Typical Use Cases for the Search will redirect to figure 2, displaying the list of sessions to which all the found messages belong. The search parameters and results description are similar to the scenario described above.
To prevent memory bloat, we strongly recommend that you load the session list by paging. For example, load by page, displaying 10 session results per page, the search parameter V2TIMMessageSearchParam can be set as follows:
1. For the first call: set searchCount = 10, searchCursor = "". Call searchCloudMessages to obtain the message search results, parse and display them on the homepage, and obtain the total number of sessions totalCount and the cursor for the next request searchCursor from the result callback.
2. When the interface is almost scrolled to the bottom, continue to pull the next page of data based on the cursor searchCursor from the previous request results.
Below is the sample code:
Android
iOS & Mac
Windows
......
// Logging the search cursor
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) {
// Total number of matched sessions to which messages belong
int totalCount = v2TIMMessageSearchResult.getTotalCount();
// Cursor for the next page
searchCursor = v2TIMMessageSearchResult.getSearchCursor();
// Information of messages classified by session
List<V2TIMMessageSearchResultItem> resultItemList = v2TIMMessageSearchResult.getMessageSearchResultItems();
for (V2TIMMessageSearchResultItem resultItem : resultItemList) {
// Session ID
String conversationID = resultItem.getConversationID();
// Total number of messages matching the session
int totalMessageCount = resultItem.getMessageCount();
// Message list: If totalMessageCount > 1, this list is empty; if totalMessageCount = 1, this list Element (XML) is this message
List<V2TIMMessage> v2TIMMessageList = resultItem.getMessageList();
}
}
@Override
public void onError(int code, String desc) {
}
});
}

// Load the next page
public void loadMore() {
searchConversation(searchCursor);
}
......
// Logging the search cursor
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) {
// Total number of matched sessions to which messages belong
NSUInteger totalCount = searchResult.totalCount;
// Cursor for the next page
searchCursor = searchResult.searchCursor;
// Information of messages classified by session
NSArray<V2TIMMessageSearchResultItem *> *messageSearchResultItems = searchResult.messageSearchResultItems;
for (V2TIMMessageSearchResultItem *searchItem in messageSearchResultItems) {
// Session ID
NSString *conversationID = searchItem.conversationID;
// Total number of messages matching the session
NSUInteger totalMessageCount = searchItem.messageCount;
// Message list: If totalMessageCount > 1, this list is empty; if totalMessageCount = 1, this list Element (XML) is this message
NSArray<V2TIMMessage *> *messageList = searchItem.messageList ?: @[];
}
} fail:^(int code, NSString *desc) {
// fail
}];
}

// Load the next page
- (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_;
};

// Logging the search cursor
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) {
// Total number of matched sessions to which messages belong
uint32_t totalCount = messageSearchResult.totalCount;
// Cursor for the next page
searchCursor = messageSearchResult.searchCursor;
// Information of messages classified by session
V2TIMMessageSearchResultItemVector messageSearchResultItems =
messageSearchResult.messageSearchResultItems;
for (size_t i = 0; i < messageSearchResultItems.Size(); ++i) {
// Session ID
V2TIMString conversationID = messageSearchResultItems[i].conversationID;
// Total number of messages matching the session
uint32_t messageCount = messageSearchResultItems[i].messageCount;
// Message list: If messageCount > 1, this list is empty; if messageCount = 1, this list Element (XML) is this message
V2TIMMessageVector messageList = messageSearchResultItems[i].messageList;
}
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Failed to find the data
delete callback;
});
V2TIMManager::GetInstance()->GetMessageManager()->SearchLocalMessages(searchParam, callback);
}

// Load the next page
void LoadMore() { SearchConversation(searchCursor); }

Displaying the Messages of a Specified Session

Unlike the session list shown in figure 2 in the Typical Use Cases for the Search, figure 3 displays the list of messages found in a specified session. To prevent memory bloat, we strongly recommend paginating the message display. For example, paginate and show 10 message results per page:
1. Search parameter V2TIMMessageSearchParam settings can be referred to as follows:
Setting the search parameter V2TIMMessageSearchParam's conversationID as the session ID you are searching for.
Initial call: Set the parameter searchCount = 10, searchCursor = "". Call searchCloudMessages to obtain the message search results, parse and display them on the homepage, and obtain the total number of sessions totalCount and the cursor for the next page searchCursor from the result callback.
Subsequent call: Update the value of searchCursor to the return value from the callback of the previous call.
2. Handling the search results V2TIMMessageSearchResult:
totalCount indicates the total number of messages matched in that session.
messageSearchResultItems list contains only the results for that session. In the list, messageCount of V2TIMMessageSearchResultItem is the number of messages on that page, and messageList is the list of messages on that page.
searchCursor represents the starting cursor for the next page search.
Below is the sample code:
Android
iOS & Mac
Windows
......
// Record the search cursor
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) {
// Total number of messages matching the session
int totalMessageCount = v2TIMMessageSearchResult.getTotalCount();
// Cursor for the next page
searchCursor = v2TIMMessageSearchResult.getSearchCursor();
// Number of messages on the current page
List<V2TIMMessageSearchResultItem> resultItemList = v2TIMMessageSearchResult.getMessageSearchResultItems();
for (V2TIMMessageSearchResultItem resultItem : resultItemList) {
// Session ID
String conversationID = resultItem.getConversationID();
// The number of messages on the current page
int totalMessageCount = resultItem.getMessageCount();
// List of messages on the current page
List<V2TIMMessage> v2TIMMessageList = resultItem.getMessageList();
}
}
@Override
public void onError(int code, String desc) {
}
});
}
// Load the next page
public void loadMore() {
searchMessage(searchCursor);
}
......
// Record the search cursor
NSString *searchCursor = @"";
......

- (void)searchMessage:(NSString *)cursor {
V2TIMMessageSearchParam *param = [[V2TIMMessageSearchParam alloc] init];
param.keywordList = @[@"test"];
// conversationID is the session ID to search
param.conversationID = conversationID;
param.searchCursor = cursor;
param.searchCount = 10;
[V2TIMManager.sharedInstance searchCloudMessages:param succ:^(V2TIMMessageSearchResult *searchResult) {
// Total number of messages matching the session
NSUInteger totalMessageCount = searchResult.totalCount;
// Cursor for the next page
searchCursor = searchResult.searchCursor;
// Messages on the current page
NSArray<V2TIMMessageSearchResultItem *> *messageSearchResultItems = searchResult.messageSearchResultItems;
for (V2TIMMessageSearchResultItem *searchItem in messageSearchResultItems) {
// Session ID
NSString *conversationID = searchItem.conversationID;
// The number of messages on the current page
NSUInteger totalMessageCount = searchItem.messageCount;
// List of messages on the current page
NSArray<V2TIMMessage *> *messageList = searchItem.messageList ?: @[];
}
} fail:^(int code, NSString *desc) {
// fail
}];
}

// Load the next page
- (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_;
};

// Record the search cursor
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) {
// The number of all messages matched by the session
uint32_t totalCount = messageSearchResult.totalCount;
// Cursor for the next page
searchCursor = messageSearchResult.searchCursor;
// Messages on the current page
V2TIMMessageSearchResultItemVector messageSearchResultItems =
messageSearchResult.messageSearchResultItems;
for (size_t i = 0; i < messageSearchResultItems.Size(); ++i) {
// Session ID
V2TIMString conversationID = messageSearchResultItems[i].conversationID;
// Number of messages on the current page
uint32_t messageCount = messageSearchResultItems[i].messageCount;
// List of messages on the current page
V2TIMMessageVector messageList = messageSearchResultItems[i].messageList;
}
delete callback;
},
[=](int error_code, const V2TIMString& error_message) {
// Search failed
delete callback;
});
V2TIMManager::GetInstance()->GetMessageManager()->SearchCloudMessages(searchParam, callback);
}

// Load the next page
void LoadMore() { SearchConversation(SearchCursor); }

Searching for a Custom Message

Typically, if you use the createCustomMessage(data) (Android/iOS & Mac/Windows) API to create a custom message, the message cannot be found because the SDK saves it as a binary data stream.
If you want your custom messages to be searchable, you must use the createCustomMessage(data, description, extension) (Android/iOS & Mac/Windows) API to create and send custom messages, placing the searchable text in the description parameter.
If you have configured the offline push feature, after setting the description parameter, your custom messages will also have offline push and the notification bar will display the content of that parameter. If you don't need offline push, you can control it with the disablePush in the V2TIMOfflinePushInfo parameter of the sendMessage (Android/iOS & Mac/Windows) API.
If you do not want the content displayed in the push notification bar to be the searchable text, you can use the desc in the V2TIMOfflinePushInfo parameter to set the push content differently.

Searching for a Rich Media Message

Rich media messages include file, image, audio, and video messages.
For file messages, the interface usually displays the file name. If you pass the fileName parameter when calling createFileMessage to create a file message, fileName will be used as the content of the file message to be searched and matched with the search keyword. If fileName is not set, the SDK will automatically extract the file name from filePath as the search content. Both fileName and filePath information is saved to the local device and server, and can be searched after pulling relevant information on a new device.
For image, audio, and video messages, there is no such name as fileName, and the interface usually displays a thumbnail or duration, making the specification of keywordList ineffective for searches. If you wish to search for such messages, you can specify messageTypeList as V2TIM_ELEM_TYPE_IMAGE/V2TIM_ELEM_TYPE_SOUND/V2TIM_ELEM_TYPE_VIDEO for categorized searches, which will then retrieve all messages of the specified types.



Exchange and Feedback

Join the Telegram technical exchange group or WhatsApp discussion group, benefit from the support of professional engineers, and solve your toughest challenges.

Contact Us

Contact our sales team or business advisors to help your business.

Technical Support

Open a ticket if you're looking for further assistance. Our Ticket is 7x24 avaliable.

7x24 Phone Support
中国香港
+852 800 906 020 (免费)
美国
+1 844 606 0804 (免费)
英国
+44 808 196 4551 (免费)
加拿大
+1 888 605 7930 (免费)
澳大利亚
+61 1300 986 386 (免费)
EdgeOne 热线
+852 300 80699
更多本地服务热线陆续新增中