I am trying to use the new App protocol for a new SwiftUI App and I need to detect a scenePhase change into .background at App level in order to persist little App data into a .plist file. I don't know if it is a bug or I am doing something wrong but it doesn't work as expected. As soon as a button is tapped, scenePhase change to .background when the scene is still active! In order to show an example of this weird behaviour, I am showing this simple code:
class DataModel: ObservableObject {
@Published var count = 0
}
@main
struct TestAppProtocolApp: App {
@Environment(\.scenePhase) private var scenePhase
@StateObject private var model: DataModel = DataModel()
var body: some Scene {
WindowGroup {
ContentView().environmentObject(model)
}
.onChange(of: scenePhase) { newScenePhase in
switch newScenePhase {
case .active:
print("Scene is active.")
case .inactive:
print("Scene is inactive.")
case .background:
print("Scene is in the background.")
@unknown default:
print("Scene is in an unknown state.")
}
}
}
}
struct ContentView: View {
@EnvironmentObject var model: DataModel
var body: some View {
VStack {
Button(action: { model.count += 1 }) {
Text("Increment")
}
.padding()
Text("\(model.count)")
}
}
}
When the increment button is tapped, scenePhase changes to .background and then, when the App is really sent to background, scenePhase is not changed.
I found out that moving the .onChange(of: scenePhase) to the View (ContentView) works fine as I expect but Apple announced you can monitor any scenePhase change at App level and this is what I really want not at View level.
Xcode12 beta 6 seems to solve the issue. Now it works as expected.