import Foundation @MainActor public final class ImSDK { public static let shared = ImSDK() private var client: ImClient? private init() {} public func login(userId: String, nickname: String? = nil, avatar: String? = nil) async throws { let config = XuqmSDK.shared.requireConfig() struct LoginResponse: Decodable { let token: String } var items = [URLQueryItem(name: "appId", value: config.appId), URLQueryItem(name: "userId", value: userId)] if let n = nickname { items.append(URLQueryItem(name: "nickname", value: n)) } if let a = avatar { items.append(URLQueryItem(name: "avatar", value: a)) } let res: LoginResponse = try await ApiClient.shared.request( path: "/api/im/auth/login", method: "POST", queryItems: items ) XuqmSDK.shared.tokenStore?.save(res.token) client = ImClient(wsURL: config.imWebSocketURL, token: res.token, appId: config.appId) client?.connect() } public func setDelegate(_ delegate: ImEventDelegate) { client?.delegate = delegate } public func sendMessage(toId: String, chatType: ChatType, msgType: MsgType, content: String) { client?.sendMessage(toId: toId, chatType: chatType, msgType: msgType, content: content) } public func disconnect() { client?.disconnect() client = nil } }