XuqmGroup-iOSSDK/Sources/XuqmSDK/IM/ImClient.swift

81 行
2.9 KiB
Swift

2026-04-21 22:07:29 +08:00
import Foundation
public final class ImClient: NSObject, URLSessionWebSocketDelegate, @unchecked Sendable {
public weak var delegate: ImEventDelegate?
private var webSocketTask: URLSessionWebSocketTask?
private var session: URLSession?
private let wsURL: URL
private let token: String
private let appId: String
private var shouldReconnect = false
public init(wsURL: URL, token: String, appId: String) {
self.wsURL = wsURL
self.token = token
self.appId = appId
super.init()
}
public func connect() {
shouldReconnect = true
var request = URLRequest(url: wsURL)
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
session = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
webSocketTask = session?.webSocketTask(with: request)
webSocketTask?.resume()
receiveMessage()
}
private func receiveMessage() {
webSocketTask?.receive { [weak self] result in
switch result {
case .success(let message):
if case .string(let text) = message {
self?.handleMessage(text)
}
self?.receiveMessage()
case .failure(let error):
self?.delegate?.imClientDidError(error.localizedDescription)
}
}
}
private func handleMessage(_ text: String) {
guard let data = text.data(using: .utf8),
let msg = try? JSONDecoder().decode(ImMessage.self, from: data) else { return }
if msg.chatType == .group {
delegate?.imClientDidReceiveGroupMessage(msg)
} else {
delegate?.imClientDidReceiveMessage(msg)
}
}
public func sendMessage(toId: String, chatType: ChatType, msgType: MsgType, content: String) {
let payload: [String: Any] = [
"type": "chat.send",
"data": ["appId": appId, "toId": toId, "chatType": chatType.rawValue,
"msgType": msgType.rawValue, "content": content]
]
guard let data = try? JSONSerialization.data(withJSONObject: payload),
let text = String(data: data, encoding: .utf8) else { return }
webSocketTask?.send(.string(text)) { _ in }
}
public func disconnect() {
shouldReconnect = false
webSocketTask?.cancel(with: .normalClosure, reason: nil)
}
public func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask,
didOpenWithProtocol protocol: String?) {
delegate?.imClientDidConnect()
}
public func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask,
didCloseWith closeCode: URLSessionWebSocketTask.CloseCode, reason: Data?) {
let reasonStr = reason.flatMap { String(data: $0, encoding: .utf8) }
delegate?.imClientDidDisconnect(reason: reasonStr)
}
}