// Copyright © 2024 Rangeproof Pty Ltd. All rights reserved. import Foundation import SessionUtilitiesKit // MARK: - Singleton public extension Singleton { // FIXME: This will be reworked to be part of dependencies in the Groups Rebuild branch fileprivate static var _appReadiness: Atomic = Atomic(AppReadiness()) static var appReadiness: AppReadiness { _appReadiness.wrappedValue } } // MARK: - AppReadiness public class AppReadiness { public private(set) var isAppReady: Bool = false private var appWillBecomeReadyBlocks: Atomic<[() -> ()]> = Atomic([]) private var appDidBecomeReadyBlocks: Atomic<[() -> ()]> = Atomic([]) public func setAppReady() { guard Thread.isMainThread else { DispatchQueue.main.async { [weak self] in self?.setAppReady() } return } // Update the flag isAppReady = true // Trigure the closures let willBecomeReadyClosures: [() -> ()] = appWillBecomeReadyBlocks.wrappedValue let didBecomeReadyClosures: [() -> ()] = appDidBecomeReadyBlocks.wrappedValue appWillBecomeReadyBlocks.mutate { $0 = [] } appDidBecomeReadyBlocks.mutate { $0 = [] } willBecomeReadyClosures.forEach { $0() } didBecomeReadyClosures.forEach { $0() } } public func invalidate() { isAppReady = false } public func runNowOrWhenAppWillBecomeReady(closure: @escaping () -> ()) { // We don't need to do any "on app ready" work in the tests. guard !SNUtilitiesKitConfiguration.isRunningTests else { return } guard !isAppReady else { guard Thread.isMainThread else { DispatchQueue.main.async { [weak self] in self?.runNowOrWhenAppWillBecomeReady(closure: closure) } return } return closure() } appWillBecomeReadyBlocks.mutate { $0.append(closure) } } public func runNowOrWhenAppDidBecomeReady(closure: @escaping () -> ()) { // We don't need to do any "on app ready" work in the tests. guard !SNUtilitiesKitConfiguration.isRunningTests else { return } guard !isAppReady else { guard Thread.isMainThread else { DispatchQueue.main.async { [weak self] in self?.runNowOrWhenAppDidBecomeReady(closure: closure) } return } return closure() } appDidBecomeReadyBlocks.mutate { $0.append(closure) } } }