iosswiftswiftuionappear

SwiftUI .onAppear, only running once


In a SwiftUI app I have code like this:

var body: some View {
    VStack {
        Spacer()
        ........
    }
    .onAppear {
      .... I want to have some code here ....
      .... to run when the view appears ....
    }
}

My problem is that I would like to run some code inside the .onAppear block, so that it gets run when the app appears on screen, after launching or after being in the background for a while. But it seems like this code is only run once at app launch, and never after. Am I missing something? Or should I use a different strategy to get the result I want?


Solution

  • You would have to observe the event when the app is entering foreground and publish it using @Published to the ContentView. Here's how:

    struct ContentView: View {
    
        @ObservedObject var observer = Observer()
    
        var body: some View {
            VStack {
                Spacer()
                //...
            }
            .onReceive(self.observer.$enteredForeground) { _ in
                print("App entered foreground!") // do stuff here
            }
        }
    }
    
    class Observer: ObservableObject {
    
        @Published var enteredForeground = true
    
        init() {
            if #available(iOS 13.0, *) {
                NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground), name: UIScene.willEnterForegroundNotification, object: nil)
            } else {
                NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
            }
        }
    
        @objc func willEnterForeground() {
            enteredForeground.toggle()
        }
    
        deinit {
            NotificationCenter.default.removeObserver(self)
        }
    }