import Foundation @MainActor public final class XuqmSDK: NSObject { public static let shared = XuqmSDK() private(set) var config: SDKConfig? private(set) var tokenStore: TokenStore? public private(set) var currentUserId: String? private var userSig: String? private var cachedDeviceToken: String? private override init() { super.init() } public func initialize(config: SDKConfig) { self.config = config self.tokenStore = TokenStore() ApiClient.shared.configure(with: config) } public func requireConfig() -> SDKConfig { guard let config else { fatalError("XuqmSDK not initialized. Call XuqmSDK.shared.initialize() first.") } return config } public func login(userId: String, userSig: String) async { self.currentUserId = userId self.userSig = userSig do { try await ImSDK.shared.loginWithUserSig(userId, userSig) } catch { // IM login failed; silently ignored per facade pattern } if let cachedDeviceToken { do { try await PushSDK.shared.registerToken(cachedDeviceToken, userId: userId) } catch { // Push registration failed } } } public func logout() async { ImSDK.shared.disconnect() if let userId = currentUserId { do { try await PushSDK.shared.unregisterToken(userId: userId) } catch { // Push unregistration failed } } tokenStore?.clear() currentUserId = nil userSig = nil cachedDeviceToken = nil } public func registerDeviceToken(_ deviceToken: Data) { let token = deviceToken.map { String(format: "%02x", $0) }.joined() self.cachedDeviceToken = token Task { @MainActor in if let userId = self.currentUserId { try? await PushSDK.shared.registerToken(token, userId: userId) } } } }