Home > database >  Why scenePhase value is .background while the app is in the foreground?
Why scenePhase value is .background while the app is in the foreground?

Time:06-01

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:

enter image description here

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 !!
            }
    }
}
  • Related