Not Receiving scenePhase Changes

I acknowledge this question is specifically about schenePhase changes, however, on macOS I am not able to receive any .background notifications when a user switches to a different app. The older NotificationCenter strategy works as I expected, on both platforms. I’ll add this to the mix for anyone who is just trying to execute some code, onForeground / onBackground on iOS and macOS.

On any view, you can attach:

.onReceive(NotificationCenter.default.publisher(for: .willResignActiveNotification)) { _ in
    doBackgroundThing()
}

The events you may care about are:

  • iOS: willResignActiveNotification & willEnterForegroundNotification
  • macOS: willResignActiveNotification & willBecomeActiveNotification

You can find all NotificationCenter Names here.

I use will* variants for background because I assume they’ll be called early in the process, and I use did* variants for foreground, because they are called regardless of whether the app is launched for the first time, or it’s coming out of background.

I use this extension so I don’t have to think about the platform differences:

extension View {
    #if os(iOS)
    func onBackground(_ f: @escaping () -> Void) -> some View {
        self.onReceive(
            NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification),
            perform: { _ in f() }
        )
    }
    
    func onForeground(_ f: @escaping () -> Void) -> some View {
        self.onReceive(
            NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification),
            perform: { _ in f() }
        )
    }
    #else
    func onBackground(_ f: @escaping () -> Void) -> some View {
        self.onReceive(
            NotificationCenter.default.publisher(for: NSApplication.willResignActiveNotification),
            perform: { _ in f() }
        )
    }
    
    func onForeground(_ f: @escaping () -> Void) -> some View {
        self.onReceive(
            NotificationCenter.default.publisher(for: NSApplication.didBecomeActiveNotification),
            perform: { _ in f() }
        )
    }
    #endif
}

As expected, I use it as such:

AppView()
   .onBackground {
       print("my background")
   }
   .onForeground {
       print("my foreground")
   }

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)