Update UI on Singleton property change without sharing dependency between Views

I want to make my UI update itself on singleton’s class property change without passing the singleton object between views as .environmentObject or any another.

I have NetworkManager class, which is singleton:

final class NetworkManager: ObservableObject {
    let monitor = NWPathMonitor()
    let queue = DispatchQueue(label: "NetworkManager")
    @Published var isConnected = true
    
    static let shared: NetworkManager = {
       NetworkManager()
    }()
    
    private init() {
        monitor.pathUpdateHandler = { path in
            DispatchQueue.main.async {
                self.isConnected = path.status == .satisfied
            }
        }
        
        monitor.start(queue: queue)
    }
}

Whenever @Published var isConnected property of this class changes, I want to update the UI for example with this piece of code: SOME_VIEW.disabled(!NetworkManager.shared.isConnected)
Unfortunately, SOME_VIEW is disabled only when I exit and entry this view once again. I want it to update itself in real time. Is it possible without @EnvironmentObject and only having my NetworkManager class as Singleton?

>Solution :

The ObservableObject updates view only via ObservedObject/StateObject/EnvironmentObject (which are actually have same nature). That wrapper (one of them) actually observers changes in published properties and refreshes view.

So your case can be solved like

struct ParentView: View {
   @StateObject private var networkNanager = NetworkManager.shared  // << observer !!

   var body: some View {
     SOME_VIEW.disabled(!networkNanager.isConnected) // injects dependency !!
   }
}

Leave a Reply