another.im-ios/Monal/another.im/XMPP/MonalXmppWrapper.swift
2024-11-21 17:03:55 +01:00

121 lines
4.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.

import Foundation
import monalxmpp
final class MonalXmppWrapper: ObservableObject {
@Published private(set) var accountsAvailability: AccountsAvailability = .noAccounts
@Published private(set) var accounts: [Account] = []
@Published private(set) var contacts: [Contact] = []
private let xmpp: MLXMPPManager
private let db: DataLayer
private var notificationObservers: [AnyObject] = []
private var isInitialized: Bool = false
init() {
// here is some inits (just for now)
MLProcessLock.initialize(forProcess: "MainApp")
// init monalxmpp components
xmpp = MLXMPPManager.sharedInstance()
db = DataLayer.sharedInstance()
// subscribe to monalxmpp notifications and fire notification for update
subscribeToUpdates()
NotificationCenter.default.post(name: Notification.Name(kMonalRefresh), object: nil)
}
deinit {
notificationObservers.forEach { NotificationCenter.default.removeObserver($0) }
}
// try login
func tryLogin(_ login: String, _ password: String) async throws {
let loginObject = LoginTry(xmpp: xmpp)
let result = await loginObject.tryLogin(login, password)
if !result {
throw AimErrors.loginError
} else {
NotificationCenter.default.post(name: Notification.Name(kMonalRefresh), object: nil)
}
}
}
// MARK: - Try login from Login screen
private final class LoginTry {
weak var xmpp: MLXMPPManager?
var successObserver: AnyObject?
var failureObserver: AnyObject?
init(xmpp: MLXMPPManager) {
self.xmpp = xmpp
}
// TODO: Добавить автовключение отключенных аккаунтов при попытке ввести тот же JID
// Обработать кейс когда бесячий monalxmpp возвращает nil при попытке добавить тот же JID
func tryLogin(_ login: String, _ password: String) async -> Bool {
async let notify = await withCheckedContinuation { [weak self] continuation in
self?.successObserver = NotificationCenter.default.addObserver(forName: Notification.Name("kMLResourceBoundNotice"), object: nil, queue: .main) { notification in
print(notification.debugDescription)
continuation.resume(returning: true)
}
self?.failureObserver = NotificationCenter.default.addObserver(forName: Notification.Name("kXMPPError"), object: nil, queue: .main) { notification in
print(notification.debugDescription)
continuation.resume(returning: false)
}
}
defer {
if let successObserver {
NotificationCenter.default.removeObserver(successObserver)
}
if let failureObserver {
NotificationCenter.default.removeObserver(failureObserver)
}
}
let accountNumber = xmpp?.login(login, password: password)
let result = await notify
if let accountNumber, !result {
xmpp?.removeAccount(forAccountID: accountNumber)
}
return result
}
}
// MARK: - Handle notifications
private extension MonalXmppWrapper {
func subscribeToUpdates() {
let generalRefresh = NotificationCenter.default.addObserver(forName: Notification.Name(kMonalRefresh), object: nil, queue: .main) { [weak self] _ in
// get accounts
let accounts = self?.db.accountList()
.compactMap { dict -> Account? in
guard let dict = dict as? NSDictionary else { return nil }
return Account(dict)
} ?? []
self?.accounts = accounts
// start connect if it initialization process
if !(self?.isInitialized ?? true) {
self?.xmpp.reconnectAll()
self?.isInitialized = true
}
// mark accounts availability
if accounts.isEmpty {
self?.accountsAvailability = .noAccounts
} else if !accounts.filter({ $0.isEnabled }).isEmpty {
self?.accountsAvailability = .allDisabled
} else {
self?.accountsAvailability = .someEnabled
}
// get contacts for active accounts
//
}
notificationObservers.append(generalRefresh)
}
}