Local Search (iOS)

Last updated: 2021-10-15 16:51:43

    Local search is supported starting from Enhanced Edition v5.4.666. To use local search, you need to purchase the Flagship Edition package. For operation details, please see Purchase Guide.

    Feature Demonstration

    The search API interface consists of three parts: the upper part is for friend search, the middle part is for group and group member search, and the lower part is for message search, where messages are classified by conversation.
    Download and install the app to experience it now.

    Integration Guide

    Scheme 1: Integrating TUIKit search source code

    Step 1. Purchase the package

    Purchase the Flagship Edition package by referring to Purchase Guide.

    Step 2. Download source code

    Download source code to integrate the TUIKit module. TUIKit supports local search starting from v5.4.666.

    pod 'TXIMSDK_TUIKit_iOS', ~>'5.4.666'
    

    Step 3. Initialize TUIKit and log in

    // Initialize TUIKit
    [[TUIKit sharedInstance] setupWithAppId:SDKAPPID];
    // Log in to TUIKit
    [[TUIKit sharedInstance] login:identifier userSig:sig succ:^{
    // Login succeeded 
    } fail:^(int code, NSString *msg) {
     // Login failed
    }];
    

    Step 4. Start the search interface

    Enable TUISearchViewController.

    Scheme 2: Integrate the IM SDK search API

    Step 1. Purchase the package

    Purchase the Flagship Edition package by referring to Purchase Guide.

    Step 2. Integrate IM SDK Enhance Edition

    The IM SDK supports local search starting from v5.4.666.

    pod 'TXIMSDK_Plus_iOS', ~>'5.4.666'
    

    Step 3. Call the local user profile search API

    You can call the searchFriends API to search for local user profiles. The API supports the following search fields: userID, nickName, and remark.

    Step 4. Call the local group and group member search APIs

    You can call the searchGroups API to search for the profiles of local groups.
    You can call the searchGroupMembers API to search for the profiles of local group members. There are two cases, depending on whether the value of groupIDList in V2TIMGroupMemberSearchParam is nil:

    • groupIDList == nil: search the members in all groups, and the returned results will be classified by group ID.
    • groupIDList != nil: search the members in a specified group.

    Step 5. Call the local message search API

    You can enter keywords in the search box to call searchLocalMessages to search for local messages. There are two cases, depending on whether the value of conversationID in the V2TIMMessageSearchParam API is nil:

    • conversationID == nil: search all conversations, and the returned results will be classified by conversation.
    • conversationID != nil: search a specified conversation.

    Displaying recent active conversations
    As shown in Figure 1, the bottom part of the search interface is the list of the last 3 conversations to which the messages found belong. The implementation method is as follows:

    • In the V2TIMMessageSearchParam API, conversationID is set to nil, indicating that the messages of all conversations are searched; pageIndex is set to 0, indicating data on page 0 of the conversations to which the messages found belong; pageSize indicates the number of recent conversations to be returned. Usually, 3 recent conversations are displayed on the UI.
    • In the search callback result API V2TIMMessageSearchResult, totalCount indicates the total number of conversations to which the matched messages belong; messageSearchResultItems indicates the information of the recent conversations (conversation quantity specified by pageSize). In V2TIMMessageSearchResultItem, conversationID indicates the conversation ID, messageCount indicates the total number of messages found in the current conversation, and messageList indicates the list of messages found. messageList has two cases:
      • If the number of messages found is greater than 1, messageList is empty. You can display related chat records (quantity specified by messageCount) on the UI.
      • If the number of messages found is equal to 1, messageList is the matched message. You can display the message content on the UI and highlight the search keyword, such as test in the above figures.

    Sample

    V2TIMMessageSearchParam *param = [[V2TIMMessageSearchParam alloc] init];
    param.keywordList = @[@"test"];
    // Setting `conversationID` to `nil` is to search for messages in all conversations and the results will be classified by conversation
    param.conversationID = nil;
    param.pageIndex = 0;
    param.pageSize = 3;
    [V2TIMManager.sharedInstance searchLocalMessages:param succ:^(V2TIMMessageSearchResult *searchResult) {
        // Total number of matched conversations to which messages belong
        NSInteger totalCount = searchResult.totalCount;
        // Last 3 messages classified by conversation
        NSArray<V2TIMMessageSearchResultItem *> *messageSearchResultItems = searchResult.messageSearchResultItems;
        for (V2TIMMessageSearchResultItem *searchItem in messageSearchResultItems) {
            // Conversation ID
            NSString *conversationID = searchItem.conversationID;
            // Total number of messages matching the conversation
            NSUInteger messageCount = searchItem.messageCount;
            // Message list
            NSArray<V2TIMMessage *> *messageList = searchItem.messageList ?: @[];
        }
    } fail:^(int code, NSString *desc) {
        // fail
    }];
    

    Displaying the list of conversations to which the messages found belong
    For example, you can click More Chat History in Figure 1 to redirect to the list of conversations to which the messages found belong, as shown in Figure 2. The search parameters and results are similar to those in the preceding scenario. To avoid memory ballooning, it is strongly recommended that you load the conversation list with pagination. For example, to display 10 conversations as the result, you can set the search parameter API V2TIMMessageSearchParam as follows:

    • First call: Set pageSize to 10 and pageIndex to 0, and call searchLocalMessages. Then you can get the total number of conversations from totalCount in the callback.
    • Page quantity calculation: totalPage = (totalCount % pageSize == 0) ? (totalCount / pageSize) : (totalCount / pageSize + 1)
    • Second call: You can specify pageIndex (pageIndex < totalPage) to return the subsequent page number.

    Sample

    ......
    // Calculate the total number of pages, given that 10 messages are displayed per page
    NSInteger totalPage = (totalCount % 10 == 0) ? (totalCount / 10) : (totalCount / 10 + 1);
    ......
    - (void)searchConversation:(NSUInteger)index {
      if (index >= totalPage) {
          return;
      }
      V2TIMMessageSearchParam *param = [[V2TIMMessageSearchParam alloc] init];
      param.keywordList = @[@"test"];
      param.conversationID = nil;
      param.pageIndex = index;
      param.pageSize = 10;
      [V2TIMManager.sharedInstance searchLocalMessages:param succ:^(V2TIMMessageSearchResult *searchResult) {
          // Total number of matched conversations to which messages belong
          NSUInteger totalCount = searchResult.totalCount;
          // Calculate the total number of pages, given that 10 messages are displayed per page
          NSUInteger totalPage = (totalCount % 10 == 0) ? (totalCount / 10) : (totalCount / 10 + 1);
          // Information of messages classified by conversation
          NSArray<V2TIMMessageSearchResultItem *> *messageSearchResultItems = searchResult.messageSearchResultItems;
          for (V2TIMMessageSearchResultItem *searchItem in messageSearchResultItems) {
              // Conversation ID
              NSString *conversationID = searchItem.conversationID;
              // Total number of messages matching the conversation
              NSUInteger totalMessageCount = searchItem.messageCount;
              // List of messages. If `totalMessageCount` is greater than 1, the list is empty. If `totalMessageCount` is equal to 1, the list contains the current message.
              NSArray<V2TIMMessage *> *messageList = searchItem.messageList ?: @[];
          }
      } fail:^(int code, NSString *desc) {
          // fail
      }];
    }
    // Load the next page
    - (void)loadMore {
      [self searchConversation:++pageIndex];
    }
    

    Searching for messages in a specified conversation
    Figure 2 shows the effect of displaying the conversation list, while Figure 3 shows the effect of displaying the list of the messages found in a specified conversation. To avoid memory ballooning, it is strongly recommended that you load the message list with pagination. The implementation method is as follows:

    Sample

    ......
    // Calculate the total number of pages, given that 10 messages are displayed per page
    NSInteger totalMessagePage = (totalMessageCount % 10 == 0) ? (totalMessageCount / 10) : (totalMessageCount / 10 + 1);
    ......
    - (void)searchMessage:(NSUInteger)index {
      if (index >= totalMessagePage) {
              return;
      }
      V2TIMMessageSearchParam *param = [[V2TIMMessageSearchParam alloc] init];
      param.keywordList = @[@"test"];
      param.conversationID = conversationID;
      param.pageIndex = index;
      param.pageSize = 10;
      [V2TIMManager.sharedInstance searchLocalMessages:param succ:^(V2TIMMessageSearchResult *searchResult) {
          // Total number of messages matching the conversation
          NSUInteger totalMessageCount = searchResult.totalCount;
          // Calculate the total number of pages, given that 10 messages are displayed per page
          NSUInteger totalMessagePage = (totalMessageCount % 10 == 0) ? (totalMessageCount / 10) : (totalMessageCount / 10 + 1);
          // Information of the messages on the conversation page
          NSArray<V2TIMMessageSearchResultItem *> *messageSearchResultItems = searchResult.messageSearchResultItems;
          for (V2TIMMessageSearchResultItem *searchItem in messageSearchResultItems) {
              // Conversation ID
              NSString *conversationID = searchItem.conversationID;
              // 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:++pageIndex];
    }
    

    FAQs

    1. How do I search for custom messages?

    Use the createCustomMessage:desc:extension API to create and send a search request. In the request, you need to specify the text to search in the desc parameter. Custom messages created via the createCustomMessage API cannot be searched because the binary data stream passed in by parameters is saved locally.
    If you configure the offline push feature and the desc parameter, custom messages will also be pushed offline, and the content specified in the desc parameter will be displayed in the notification bar. If offline push is not needed, disable it using disablePush in V2TIMOfflinePushInfo in the sendMessage API. If you do not want to display the searched text in the push notification bar, set other push content using desc in V2TIMOfflinePushInfo.

    2. How do I search for rich media messages?

    Rich media messages include file, image, voice, and video messages.
    For file messages, the screen usually displays the filename. Therefore, you can set the fileName parameter as the searched content when creating messages. If fileName is not set, the system gets the filename from filePath and saves it to the local storage and the server.
    For image, voice, and video messages, the screen usually displays the thumbnail or duration. In this case, you can specify the message type to search by type, but cannot search by keywords.