SendBird:搜索个人聊天和群聊

问题描述

SendBird 将每个频道视为它们的 GroupChannel。从技术上讲,一对一聊天也是一个只有两个用户GroupChannel(使用 isdistinct = true,因此当您再次尝试创建时它会返回个人聊天)。

我的问题是,如何按名称搜索 GroupChannel,其中包括群组和 1:1 聊天?群聊将有一个通用名称,该名称显示给该群中的所有用户。但是对于 1:1 聊天,GroupChannel 不会有姓名,如果有,则不会向用户显示,对于 1:1 聊天,我们总是显示对方的姓名(例如几乎所有的聊天系统都可以工作)。

通常,主界面列表包含群聊和一对一聊天(所有 GroupChannel)。

 --------------------------------
|    Search Chat TextField       |
|--------------------------------|
|1  John (1:1)                   |
|2  John's Birthday Plan (group) |
|3  Johnney Eve (1:1)            |
|4  Johansson Fans (group)       |
|  ...                           |
 --------------------------------

所有项目在技术上都是 GroupChannel。请注意,所有 1:1 聊天都没有实际的 name,如列表中所示。列表中显示的姓名是其他人的 nickname

期望:

现在,如果用户搜索诸如“joh”之类的内容,那么它应该返回名称包含“joh”的所有群聊或其他人姓名包含“joh”的所有 1:1 聊天。 (基本上是上面例子中显示的所有项目。)

我的尝试:

我最初的解决方案是将 1:1 频道名称保留为 <user1 nickname> & <user2 nickname>,这样当用户名称搜索其他用户时,1:1 频道看起来就像一个群组频道.

示例代码

query = SBDGroupChannel.createMyGroupChannelListQuery()
query?.order = .latestLastMessage
query?.limit = 30
query?.channelNameContainsFilter = "joh"
query.loadNextPage(...)

问题:

问题在于:

  1. 如果用户搜索他们自己的名字(或只是分隔符 & 或只是一个空格),那么所有个人聊天都将可见,这是无关紧要的。
  2. 我的系统允许用户更改昵称,因此每次用户更改昵称时,所有 1:1 频道名称都必须更新(这很痛苦)。

解决方法

苏尼尔

通常,当您为用户 retrieve a list of group channels 时,它会检索该用户可能参与的所有频道(取决于 memberStateFilter)。

如果您明确希望search,而不是提供用户所属频道的持续列表,您或许可以filter channels by userIds。您必须筛选由搜索用户和所需用户组成的频道。

让我们看一个例子,假设您的 userId 是 John 并且您正在寻找与 Jay 的聊天:

let listQuery = SBDGroupChannel.createMyGroupChannelListQuery()
listQuery?.userIdsExactFilter = ["John","Jay"]
listQuery?.loadNextPage(completionHandler: { (groupChannels,error) in
guard error == nil else {
    // Handle error.
}

// Only channelA is returned in a result list through the "list" parameter of the callback method.
...
})

如果您想明确使用 nicknames

let listQuery = SBDGroupChannel.createMyGroupChannelListQuery()
listQuery?.nicknameContainsFilter = ["John",error) in
guard error == nil else {
    // Handle error.
}

// Only channelA is returned in a result list through the "list" parameter of the callback method.
...
})

您提到您允许用户更改其昵称,因此必须更新房间。可能值得给您的群组频道(甚至 1:1)通用名称,然后动态生成每个聊天的显示名称。 由于每个频道都返回成员列表,因此您可以查看成员数组,过滤掉已登录的用户,然后从数组中提取剩余用户的昵称。这将确保无论用户将昵称更改为什么,它始终准确无误,并且您不必在用户更新昵称时更新每个频道。

************ 02/10 更新 ************

感谢您提供您希望实现的目标的示例。看起来您实际上是在尝试使用 OR 运算符搜索 channelNameContainsFilternicknameContainsFilter。这不是我们 (Sendbird) 目前在 iOS SDK 中支持的东西。那么问题来了,你能做些什么来实现这一目标?

一种选择是利用平台 API 来获取此信息。 List my group channels 具有 search_querysearch_fields 参数,它们允许您利用 OR 运算符来查找与您的值匹配的频道名称和昵称。

或者,由于 SDK 确实返回过滤这些结果所需的所有必要数据,您可以创建一个前端过滤器,只显示与您的过滤结果匹配的项目。因此,SDK 会返回完整的频道列表,您存储该列表,然后当用户搜索时,您可以过滤列表以查找符合您需求的频道并仅显示这些频道。

作为旁注,Stackoverflow 可能不是此类讨论的最佳场所,因为有很多来回讨论。请随时加入我们的社区以获得更多支持。