I want to do something from the model file when the app goes to the background, like stop the timer or something else. But when I run the app and check for the scenePhase
value it returns .background
while the app is in the foreground.
import SwiftUI
import Combine
class Model {
@Environment(\.scenePhase) var scenePhase
var timerSubscription: AnyCancellable?
init() {
timerSubscription = Timer.publish(every: 1, on: .main, in: .common).autoconnect().sink { _ in
if self.scenePhase == .background {
// do something when the app goes to the background.
}
print(self.scenePhase) // print background while the app is in the foreground.
}
}
}
struct ContentView: View {
var model = Model()
var body: some View {
Text("Hello, world!")
.padding()
}
}
CodePudding user response:
Carefully read first sentence to the end:
Update:
what do you suggest to achieve the logic I described in the model file?
Move environment to view, where it should be, and inject it back into model when view have it or detect change on it, like
class Model {
var scenePhase: ScenePhase?
var timerSubscription: AnyCancellable?
init() {
timerSubscription = Timer.publish(every: 1, on: .main, in: .common).autoconnect().sink { _ in
if self.scenePhase == .background {
// do something when the app goes to the background.
}
print(self.scenePhase ?? .none) // print background while the app is in the foreground.
}
}
}
struct ContentView: View {
@Environment(\.scenePhase) var scenePhase // << here !!
var model = Model()
var body: some View {
Text("Hello, world!")
.padding()
.onChange(of: scenePhase) {
self.model.scenePhase = $0 // << update !!
}
.onAppear {
self.model.scenePhase = scenePhase // << initial !!
}
}
}