Search code examples
macosswiftuicombine

How to conform AppDelegate to ObservableObject?


I'm trying to observe a value in macOS AppDelegate but I got an Error:

ContentView.swift:14:6: Generic struct 'ObservedObject' requires that 'NSApplicationDelegate?' conform to 'ObservableObject'

When I try to cast the object into ObservedObject with as! ObservedObject I have another Error:

ContentView.swift:14:6: Generic struct 'ObservedObject' requires that 'ObservedObject' conform to 'ObservableObject'

AppDelegate.swift:

import Cocoa
import SwiftUI
import Combine

@NSApplicationMain
class AppDelegate: NSObject, ObservableObject, NSApplicationDelegate  {
    var isFocused = true
    
    // Other code app life-cycle functions
}

ContentView.swift:

import SwiftUI
import Combine

struct ContentView: View {
    @ObservedObject var appDelegate = NSApplication.shared.delegate
    
    // Other UI code
}

Solution

  • This looks like mix of concepts.. I'd recommend to avoid such... instead created explicit observable class.

    Like below (sketch)

    class AppState: ObservableObject {
      @Published var isFocused = true
    }
    
    @NSApplicationMain
    class AppDelegate: NSObject, NSApplicationDelegate  {
        var appState = AppState()
        
        // Other code app life-cycle functions
    
         // in place where ContentView is created
         ...
         ContentView().environmentObject(self.appState)
         ...
    }
    

    and in ContentView just use it

    struct ContentView: View {
        @EnvironmentObject var appState: AppState
        
        // Other UI code
    
        var body: some View {
           // .. use self.appState.isFocused where needed
        }
    }