jsdw_ios/QuickLocation/Section/Group/GroupIMService.swift

170 lines
5.4 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// GroupIMService.swift
// QuickLocation
//
// Created by on 2026/6/4.
//
import Foundation
import OpenIMSDK
final class GroupIMService {
static let shared = GroupIMService()
private var isInited = false
private var isLogining = false
///
private var pendingLoginCompletions: [(Bool) -> Void] = []
private init() {}
// MARK: - Init SDK
func initSDK() {
// SDK
guard !isInited else { return }
isInited = true
let config = OIMInitConfig()
config.apiAddr = URLManager.shared.openIM_API
config.wsAddr = URLManager.shared.openIM_WS
config.platform = .iPhone
OIMManager.manager.initSDK(with: config,
onConnecting: {},
onConnectFailure: { _, _ in },
onConnectSuccess: {},
onKickedOffline: {},
onUserTokenExpired: {},
onUserTokenInvalid: { _ in })
}
// MARK: - Login
///
func ensureLogin(completion: @escaping (Bool) -> Void) {
if OIMManager.manager.getLoginStatus() == .logged {
completion(true)
return
}
login(completion: completion)
}
func login(completion: @escaping (Bool) -> Void) {
//
if OIMManager.manager.getLoginStatus() == .logged {
completion(true)
return
}
guard let token = AppContextManager.shared.imToken, !token.isEmpty else {
completion(false)
return
}
let userId = AppContextManager.shared.userId
guard !userId.isEmpty else {
completion(false)
return
}
//
pendingLoginCompletions.append(completion)
guard !isLogining else { return }
isLogining = true
OIMManager.manager.login(userId, token: token) { [weak self] _ in
self?.finishLogin(success: true)
} onFailure: { [weak self] code, msg in
print("OpenIM login failed: \(code) \(msg ?? "")")
self?.finishLogin(success: false)
}
}
private func finishLogin(success: Bool) {
isLogining = false
let callbacks = pendingLoginCompletions
pendingLoginCompletions.removeAll()
callbacks.forEach { $0(success) }
}
// MARK: - Logout
func logout(completion: ((Bool) -> Void)? = nil) {
OIMManager.manager.logoutWith(onSuccess: { (_: String?) in
completion?(true)
}, onFailure: { (code: Int, msg: String?) in
print("OpenIM logout failed: \(code) \(msg ?? "")")
completion?(false)
})
}
// MARK: - Get Joined Groups
func getJoinedGroups(completion: @escaping ([OIMGroupInfo]) -> Void) {
OIMManager.manager.getJoinedGroupListWith(onSuccess: { groups in
completion(groups ?? [])
}, onFailure: { code, msg in
print("GroupIMService: getJoinedGroups failed: \(code) \(msg ?? "")")
completion([])
})
}
// MARK: - Conversation List (for unread count & last msg time)
func getConversationList(completion: @escaping ([OIMConversationInfo]) -> Void) {
OIMManager.manager.getAllConversationListWith(onSuccess: { list in
completion(list ?? [])
}, onFailure: { code, msg in
completion([])
})
}
// MARK: - Conversation Listener
private var conversationListener: ConversationListenerProxy?
func setConversationListener(_ handler: @escaping ([OIMConversationInfo]) -> Void) {
conversationListener = ConversationListenerProxy(handler: handler)
OIMManager.callbacker.addConversationListener(listener: conversationListener!)
}
// MARK: - Group Listener
private var groupListener: GroupListenerProxy?
/// /退/ SDK
func setGroupListener(_ handler: @escaping () -> Void) {
groupListener = GroupListenerProxy(handler: handler)
OIMManager.callbacker.addGroupListener(listener: groupListener!)
}
}
// MARK: - GroupListenerProxy
private class GroupListenerProxy: NSObject, OIMGroupListener {
private let handler: () -> Void
init(handler: @escaping () -> Void) {
self.handler = handler
}
func onJoinedGroupAdded(_ groupInfo: OIMGroupInfo) {
handler()
}
func onJoinedGroupDeleted(_ groupInfo: OIMGroupInfo) {
handler()
}
func onGroupInfoChanged(_ changeInfo: OIMGroupInfo) {
handler()
}
}
// MARK: - ConversationListenerProxy
private class ConversationListenerProxy: NSObject, OIMConversationListener {
private let handler: ([OIMConversationInfo]) -> Void
init(handler: @escaping ([OIMConversationInfo]) -> Void) {
self.handler = handler
}
func onConversationChanged(_ conversations: [OIMConversationInfo]) {
handler(conversations)
}
func onNewConversation(_ conversations: [OIMConversationInfo]) {
handler(conversations)
}
}