// // AccountServiceUpdate.swift // Malinka // // Created by NUT.Tech on 29.09.2022. // Copyright © 2022 NUT.Tech. All rights reserved. // import Foundation import Combine import WalletFoundation import WalletKit import WalletNetwork extension Account.Service { final class Update { // MARK: - Constants private enum Constants { static let timerInterval = 3 static let maximumRefreshCount = 5 } static let shared = Update() // MARK: - Properties var selected: WalletKit.Wallet? { Accounts().current } var accounts: [WalletKit.Wallet] { Account.Service.shared.collection } private let updateSubject = CurrentValueSubject(()) var updatePublisher: AnyPublisher { self.updateSubject.eraseToAnyPublisher() } private let accountService: AccountService? private var timerPublisher: DispatchTimer? private var refreshSubscription: AnyCancellable? // MARK: - Init private init() { let record = ApplicationEnvironment.shared().current if let environment = try? record.networkEnvironment() { self.accountService = AccountService(environment: environment) } else { self.accountService = nil } } // MARK: - Methods func updateAccountsStates(times: Int? = nil) { guard !self.refreshSubscription.isExist else { return } let publisher = Publishers.timer(queue: DispatchQueue.global(qos: .background), interval: .seconds(Constants.timerInterval), times: .max(times ?? Constants.maximumRefreshCount)) self.timerPublisher = publisher self.refreshSubscription = publisher.sink(receiveCompletion: { [weak self] _ in self?.timerPublisher = nil self?.refreshSubscription = nil }, receiveValue: { [weak self] _ in self?.refresh() }) } // MARK: - Private private func refresh() { Task { let wallets = Account.Service.shared.collection guard wallets.first(where: { $0.state != .accepted && $0.state != .declined }).isExist else { self.refreshSubscription?.cancel() self.refreshSubscription = nil self.timerPublisher = nil self.updateSubject.send() return } let bank = Account.Service.shared.bank try? await bank.refreshStatus(wallet: nil) self.updateSubject.send() } } } }