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
Name
s 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")
}