有奖捉虫:云通信与企业服务文档专题,速来> HOT

从增强版5.4.666版本开始支持本地搜索。使用前需要购买旗舰版套餐包,请参见 购买指引

功能展示

搜索接口的界面分为以下部分,最上面是搜索好友,中间部分是搜索群组、群成员,最下面是搜索消息且按照会话分组。
您可通过 下载安装应用 即刻体验,其使用效果如下:

对接指引

方案一、对接 TUIKit 搜索源码

步骤1:购买套餐包

请单击前往 购买旗舰版套餐包

步骤2:下载源码

下载源码 集成 tuikit module。TUIKit 从5.4.666版本开始支持本地搜索。

pod 'TXIMSDK_TUIKit_iOS', ~>'5.4.666'

步骤3:初始化 TUIKit 并登录

// 初始化
[[TUIKit sharedInstance] setupWithAppId:SDKAPPID];
// 登录
[[TUIKit sharedInstance] login:identifier userSig:sig succ:^{
    // 登录成功 
} fail:^(int code, NSString *msg) {
   // 登录失败
}];

步骤4:启动搜索界面

启动 TUISearchViewController 即可。

方案二、对接 IM SDK 搜索接口

步骤1:购买套餐包

请单击前往 购买旗舰版套餐包

步骤2:集成增强版 IM SDK

从5.4.666版本开始支持本地搜索。

pod 'TXIMSDK_Plus_iOS', ~>'5.4.666'

步骤3:调用搜索本地用户资料接口

调用接口 searchFriends 可以搜索本地用户资料,支持搜索 userIDnickNameremark 字段。效果如下:

步骤4:调用搜索本地群组和群成员接口

图1:搜索群组 图2:搜索更多群组

调用接口 searchGroups 可以搜索本地群组资料。
调用接口 searchGroupMembers 可以搜索本地群成员资料,根据 V2TIMGroupMemberSearchParam 中的 groupIDList 是否为 nil,分为两种情况:

  • 如果设置 groupIDList == nil,代表搜索全部群中的群成员,返回的结果会按照 groupID 进行分类;
  • 如果设置 groupIDList != nil,代表搜索指定群中的群成员。

步骤5:调用搜索本地消息接口

在搜索框输入关键字可以调用 searchLocalMessages 搜索本地消息。根据搜索参数 V2TIMMessageSearchParam 中的 conversationID 是否为 nil,分为两种情况:

  • 如果设置 conversationID == nil,代表搜索全部会话,返回的结果会按照消息所属的会话进行分类。
  • 如果设置 conversationID != nil,代表搜索指定会话。

界面的展示通常分为如下图的几个场景:

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

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

示例

  V2TIMMessageSearchParam *param = [[V2TIMMessageSearchParam alloc] init];
  param.keywordList = @[@"test"];
  // conversationID 设置为 nil 表示搜索所有会话中的消息,结果会按照会话分类
  param.conversationID = nil;
  param.pageIndex = 0;
  param.pageSize = 3;
  [V2TIMManager.sharedInstance searchLocalMessages: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
  }];

展示所有搜索到的消息所属的会话列表
例如点击图1中的“更多聊天记录”跳转到图2来展示所有搜索到的消息所属的会话列表,其中的搜索参数和搜索结果描述跟上面的场景类似。为了防止内存膨胀,强烈建议对会话列表分页加载。比如您希望每页展示10条会话结果,搜索参数 V2TIMMessageSearchParam 可以参考如下设置:

  • 首次调用:设置参数 pageSize = 10,pageIndex = 0,调用 searchLocalMessages 从结果回调中的 totalCount 可以获取会话总数量;
  • 计算页数:totalPage = (totalCount % pageSize == 0) ? (totalCount / pageSize) : (totalCount / pageSize + 1) 。
  • 再次调用:可以通过指定参数 pageIndex(pageIndex < totalPage)返回后续页号的结果

示例

......
// 每页展示数量为10条,计算总页数
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) {
        // 匹配到的消息所属的所有会话数量
        NSUInteger totalCount = searchResult.totalCount;
        // 每页展示数量为10条,计算总页数
        NSUInteger totalPage = (totalCount % 10 == 0) ? (totalCount / 10) : (totalCount / 10 + 1);
        // 该页的根据消息会话分类的信息
        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:++pageIndex];
}

搜索指定会话中的消息
与图2展示会话列表不同的是,图3所示为在指定会话中搜索的消息列表。为了防止内存膨胀,强烈建议对消息列表分页加载。实现方式如下:

示例

......
// 每页展示数量为10条,计算总页数
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) {
        // 该会话匹配到的所有消息数量
        NSUInteger totalMessageCount = searchResult.totalCount;
        // 每页展示数量为10条,计算总页数
        NSUInteger totalMessagePage = (totalMessageCount % 10 == 0) ? (totalMessageCount / 10) : (totalMessageCount / 10 + 1);
        // 该页消息信息
        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:++pageIndex];
}

常见问题

1、如何搜索自定义消息

需要使用接口 createCustomMessage:desc:extension 来创建并发送,把需要搜索的文本放到 desc 参数中。而使用接口 createCustomMessage 创建的自定义消息由于本地保存的是参数传的二进制数据流,因此无法被搜索到。
如果您配置了离线推送功能,参数 desc 设置后,自定义消息也会有离线推送且通知栏展示该参数内容。如果不需要离线推送可以用发消息接口 sendMessage 的参数 V2TIMOfflinePushInfo 中的 disablePush 来控制;如果推送的通知栏内容不想展示为被搜索的文本,可以用参数 V2TIMOfflinePushInfo 中的 desc 来另外设置推送内容。

2、如何搜索富媒体消息

富媒体消息包含文件、图片、语音、视频消息。
对于文件消息,界面通常显示文件名,因此创建时可以设置 fileName 参数,作为被搜索的内容,如果 fileName 不设置则会从 filePath 提取文件名,并且都会保存到本地和服务器。
而对于图片、语音、视频消息,界面通常显示缩略图或时长,可以指定消息类型做分类搜索,但不能通过关键字搜索。