会话标记
会话标记
功能说明
会话标记用于为会话添加业务分类,例如标星、待处理或重要客户等。iOS SDK 支持为单聊、群聊和聊天室会话添加或移除标记。
SDK 提供 EMMarkType0 至 EMMarkType19 共 20 个标记,单个会话最多可同时包含 20 个标记。各标记与业务含义之间的映射由应用自行定义和维护。在 Swift 中,对应枚举值为 .markType0 至 .markType19。
let markMapping: [EMMarkType: String] = [
.markType0: "important",
.markType1: "pending",
.markType2: "customer"
]
提示
会话标记只用于业务分类和筛选,不会影响会话未读数、消息收发、消息已读状态或会话置顶状态。
功能开通
会话标记属于服务端会话列表功能的一部分。使用前,需要在 环信控制台 开通服务端会话列表功能。
前提条件
开始前,请确保满足以下条件:
添加会话标记
调用 addConversationMark 为一个或多个会话添加指定标记。该操作会同时更新服务端和本地的会话标记,单次最多传入 20 个会话 ID。
添加会话标记后,SDK 会同时更新服务端和本地的标记数据。初始化 SDK 前,将 EMOptions#dataSyncType 配置为包含 EMDataSyncTypeConversations。登录后,当 syncDataFinished 通知会话数据同步成功时,可通过本地会话列表接口获取 EMConversation 对象,并通过 EMConversation#marks 获取该会话的全部标记。
若服务端会话列表达到数量限制(默认最多 100 个会话),服务端可能根据会话活跃度移除不活跃会话,对应标记也可能不再随服务端会话列表同步到本地。
let conversationIds = [
"user2",
"group1"
]
EMClient.shared().chatManager?.addConversationMark(
conversationIds,
mark: .markType0
) { error in
if let error {
print("添加会话标记失败:\(error.errorDescription)")
} else {
print("会话标记添加成功")
}
}
参数说明如下:
| 参数 | 类型 | 说明 |
|---|---|---|
conversationIds | [String] | 会话 ID 数组,不能为空,单次最多传入 20 个。 - 单聊:对端用户 ID。 - 群聊:群组 ID。 - 聊天室:聊天室 ID。 |
mark | EMMarkType | 要添加的标记,取值为 .markType0 至 .markType19。 |
completion | (EMError?) -> Void | 异步操作结果。error == nil 表示成功,否则可通过 EMError#code 和 EMError#errorDescription 处理失败。 |
提示
会话标记不会将会话标为“消息已读”或“消息未读”。如需清除会话未读数,应使用会话未读数接口。
移除会话标记
调用 removeConversationMark 从一个或多个会话中移除指定标记。该操作会同时更新服务端和本地的会话标记,单次最多传入 20 个会话 ID。
let conversationIds = [
"user2",
"group1"
]
EMClient.shared().chatManager?.removeConversationMark(
conversationIds,
mark: .markType0
) { error in
if let error {
print("移除会话标记失败:\(error.errorDescription)")
} else {
print("会话标记移除成功")
}
}
removeConversationMark 的参数规则与 添加标记 接口相同。移除某个标记不会影响该会话已有的其他标记。
按标记筛选会话列表
应用应在初始化 SDK 前将 EMOptions#dataSyncType 配置为包含 .conversations,登录后等待会话数据同步完成,再通过本地 EMConversation#marks 筛选会话。
初始化 SDK 前配置会话同步:
let options = EMOptions(appkey: "your-org#your-app")
options.dataSyncType = [.conversations]
if let error = EMClient.shared().initializeSDK(with: options) {
print("SDK 初始化失败:\(error.errorDescription)")
}
通过 syncDataFinished 监听会话数据同步结束。error == nil 且 type 包含 .conversations 时,可以读取本地会话列表并筛选:
final class ConversationMarkSyncListener: NSObject, EMClientDelegate {
func syncDataFinished(_ error: EMError?, type: EMDataSyncType) {
guard error == nil, type.contains(.conversations) else {
return
}
let conversations =
EMClient.shared().chatManager?.getAllConversations(true) ?? []
let targetMark = NSNumber(value: EMMarkType.markType0.rawValue)
let markedConversations = conversations.filter { conversation in
conversation.marks.contains(targetMark)
}
// 使用 markedConversations 刷新业务列表。
}
}
let syncListener = ConversationMarkSyncListener()
EMClient.shared().add(syncListener, delegateQueue: nil)
如需从本地数据库加载会话并按标记筛选,也可以直接使用 filterConversationsFromDB:
let targetMark = NSNumber(value: EMMarkType.markType0.rawValue)
let markedConversations = EMClient.shared().chatManager?
.filterConversationsFromDB(
cleanMemoryCache: false,
filter: { conversation in
conversation.marks.contains(targetMark)
}
) ?? []
如需获取单个本地会话的全部标记,调用 getConversation 获取会话,再读取 EMConversation#marks:
let conversation = EMClient.shared().chatManager?.getConversation(
"conversationId",
type: .chat,
createIfNotExist: false
)
let marks = conversation?.marks ?? []
提示
getAllConversations、filterConversationsFromDB 和 getConversation 均读取本地数据,不会主动向服务器请求最新标记。需要最新服务端状态时,应先等待会话数据同步成功。
监听会话列表更新
本地会话列表发生变化时,SDK 通过 conversationListDidUpdate 返回更新后的会话数组。应用可以重新筛选带有目标标记的会话并刷新 UI。
final class ConversationMarkListListener: NSObject, EMConversationDelegate {
func conversationListDidUpdate(
_ conversationList: [EMConversation]
) {
let targetMark = NSNumber(value: EMMarkType.markType0.rawValue)
let markedConversations = conversationList.filter { conversation in
conversation.marks.contains(targetMark)
}
// 使用 markedConversations 刷新 UI。
}
}
let listListener = ConversationMarkListListener()
EMClient.shared().chatManager?.addConversation(delegate: listListener, queue: nil)
// 不再需要监听时移除。
EMClient.shared().chatManager?.removeConversation(delegate: listListener)
同一用户在其他设备添加或移除会话标记时,当前设备可通过 multiDevicesConversationEvent 收到 .conversationUpdateMark 事件,对应 Objective-C 枚举值为 EMMultiDevicesEventConversationUpdateMark,数值为 63。
final class ConversationMarkMultiDeviceListener:
NSObject,
EMMultiDevicesDelegate {
func multiDevicesConversationEvent(
_ event: EMMultiDevicesEvent,
conversationId: String,
conversationType: EMConversationType
) {
guard event == .conversationUpdateMark else {
return
}
// 其他设备更新了会话标记,重新读取本地会话并刷新 UI。
let conversations =
EMClient.shared().chatManager?.getAllConversations(true) ?? []
}
}
let multiDeviceListener = ConversationMarkMultiDeviceListener()
EMClient.shared().addMultiDevices(
delegate: multiDeviceListener,
queue: nil
)
// 不再需要监听时移除。
EMClient.shared().removeMultiDevicesDelegate(multiDeviceListener)
注意事项
- 会话标记支持单聊、群聊和聊天室会话。
- Objective-C 标记值为
EMMarkType0至EMMarkType19,Swift 对应.markType0至.markType19;具体业务含义由应用维护。 - 单个会话最多可以同时包含 20 个标记。
addConversationMark和removeConversationMark可同时操作多个会话,单次最多传入 20 个会话 ID。- 会话 ID 数组不能为空。调用失败时,应根据 completion 中的
EMError#code和EMError#errorDescription处理。 - 会话标记会同时更新服务端和本地会话数据,并同步到当前用户的其他设备。
- 会话标记不影响会话未读数、消息已读状态、消息收发或会话置顶状态。
- 应在会话数据同步完成后,通过本地接口读取并筛选会话。
- 若服务端会话列表达到数量限制,不活跃会话可能被移出服务端会话列表,对应标记也可能不再随会话列表返回。
接口列表
| API 名称 | 所属模块/类型 | 说明 |
|---|---|---|
addConversationMark | IEMChatManager | 为一个或多个会话添加指定标记,同时更新服务端和本地。 |
removeConversationMark | IEMChatManager | 从一个或多个会话中移除指定标记,同时更新服务端和本地。 |
dataSyncType | EMOptions | 设置登录后自动同步的数据类型。 |
initializeSDKWithOptions | EMClient | 使用指定配置初始化 iOS SDK。 |
getAllConversations | IEMChatManager | 获取排序后的本地会话数组。 |
filterConversationsFromDB | IEMChatManager | 从本地数据库读取并筛选会话。 |
getConversation | IEMChatManager | 获取指定类型的本地会话对象。 |
marks | EMConversation | 获取会话的全部标记,返回 NSArray<NSNumber *>,Swift 中为 [NSNumber]。 |
