Can SwiftUI View Receive a Call When Window Will Close?

I have an NSStatusBar application. This is my first in SwiftUI. And I need to know when the window is closed so that I can disable some of menu commands. I can use NSWindowDelegate with AppDelegate as follows.

import SwiftUI

@main
struct SomeApp: App {
    @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    @StateObject private var menuViewModel = MenuViewModel()
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(menuViewModel)
        }
    }
}

class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
    private var menuViewModel = MenuViewModel()
    
    func applicationDidFinishLaunching(_ notification: Notification) {
        if let window = NSApplication.shared.windows.first {
            window.setIsVisible(false)
            window.delegate = self
        }
    }
    
    func windowWillClose(_ notification: Notification) {
        menuViewModel.windowClosed = true
    }
}

When the window will close, MenuViewModel (ObservableObject) will receive a call, which I want my ContentView to receive. But, so far, it won't.

import SwiftUI

struct ContentView: View {
    var body: some View {
        ZStack {
        	...
        	...
        }
        .onReceive(statusBarViewModel.$windowClosed) { result in
        	// never called...
        }
    }
}

Can a SwiftUI View receive a call somehow when its window closes? Muchos thankos.

Answered by DTS Engineer in 801198022

@Tomato Use ScenePhase and observe the scenePhase from your WindowGroup. It would get triggered when the scene is in the foreground and interactive, inactive or isn’t currently visible in the UI.

    @Environment(\.scenePhase) private var scenePhase

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .onChange(of: scenePhase) { _, _ in
            switch scenePhase {
            case .active:
                print("App is active")
            case .inactive:
                print("App is inactive")
            case .background:
                print("App is in the background")
            @unknown default:
                print("Unexpected new value.")
            }
        }
    }

@Tomato Use ScenePhase and observe the scenePhase from your WindowGroup. It would get triggered when the scene is in the foreground and interactive, inactive or isn’t currently visible in the UI.

    @Environment(\.scenePhase) private var scenePhase

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .onChange(of: scenePhase) { _, _ in
            switch scenePhase {
            case .active:
                print("App is active")
            case .inactive:
                print("App is inactive")
            case .background:
                print("App is in the background")
            @unknown default:
                print("Unexpected new value.")
            }
        }
    }
Can SwiftUI View Receive a Call When Window Will Close?
 
 
Q