实时事件流监听 (AsyncStream)
与原版 Objective-C OpenIMSDK 采用单点 Delegate 回调不同,QXJIMSDK 内置了线程安全的多播事件广播器 IMEventBroadcaster,将底层全部 7 大监听器转换为标准 Swift AsyncStream。
- 支持多处同时订阅:例如会话列表 ViewModel 与聊天详情页 ViewModel 可以同时订阅
messageEvents.stream(),互不干扰、不会互相覆盖。 - 自动生命周期管理:当承载
for await的 SwiftTask被cancel()(如 SwiftUI 视图.task {}随页面销毁自动取消)时,IMEventBroadcaster会通过onTermination自动清理对应的Continuation,无内存泄漏。
1. 事件流一览表
多播流属性 (QXJIMClient.shared) | 事件元素类型 | 对应底层监听协议 |
|---|---|---|
connectionEvents.stream() | IMConnectionEvent | OnConnListener |
conversationEvents.stream() | IMConversationEvent | OnConversationListener |
inputStatusEvents.stream() | IMInputStatusChangedData | onConversationUserInputStatusChanged (专项流) |
messageEvents.stream() | IMMessageEvent | OnAdvancedMsgListener |
groupEvents.stream() | IMGroupEvent | OnGroupListener |
friendshipEvents.stream() | IMFriendshipEvent | OnFriendshipListener |
userEvents.stream() | IMUserEvent | OnUserListener |
userStatusEvents.stream() | IMUserOnlineStatus | onUserStatusChanged (专项流) |
customBusinessEvents.stream() | String (JSON) | OnCustomBusinessListener |
2. 在 SwiftUI / ViewModel 中订阅示例
2.1 监听连接与 Token 状态 (connectionEvents)
Task {
for await event in QXJIMClient.shared.connectionEvents.stream() {
switch event {
case .connecting:
print("正在连接 IM 服务器...")
case .connected:
print("IM 服务器连接成功")
case .connectFailed(let error):
print("IM 连接失败: \(error.localizedDescription)")
case .kickedOffline:
print("当前账号在其他设备登录,已被踢下线")
case .userTokenExpired:
print("IM Token 已过期,请重新登录")
case .userTokenInvalid(let reason):
print("IM Token 无效: \(reason)")
}
}
}
2.2 监听会话变更与数据同步进度 (conversationEvents)
Task {
for await event in QXJIMClient.shared.conversationEvents.stream() {
switch event {
case .syncServerStart(let reinstalled):
print("开始同步服务端会话数据 (是否重装: \(reinstalled))")
case .syncServerProgress(let progress):
print("同步进度: \(progress)%")
case .syncServerFinish:
print("服务端会话数据同步完成")
case .syncServerFailed:
print("服务端会话数据同步失败")
case .newConversations(let list), .conversationsChanged(let list):
// 局部增量更新本地会话列表 UI
await updateConversationListUI(with: list)
case .totalUnreadCountChanged(let totalUnread):
// 更新底部 TabBar 消息未读角标
await updateTabBadge(count: Int(totalUnread))
case .userInputStatusChanged(let inputData):
print("用户 \(inputData.userID) 正在输入: \(inputData.isTyping)")
}
}
}
2.3 监听新消息、已读回执与消息撤回 (messageEvents)
Task {
for await event in QXJIMClient.shared.messageEvents.stream() {
switch event {
case .receivedNewMessage(let msg):
await appendIncomingMessage(msg)
case .receivedOfflineNewMessage(let msg):
await appendIncomingMessage(msg)
case .receivedOnlineOnlyMessage(let msg):
await handleSignalingOrOnlineOnlyMessage(msg)
case .c2cReadReceipts(let receipts):
await markLocalMessagesAsReadByPeer(receipts)
case .messageRevoked(let revokedInfo):
await markLocalMessageAsRevoked(revokedInfo)
case .messageDeleted(let deletedMsg):
await removeMessageFromUI(deletedMsg.clientMsgID)
}
}
}