Kunal Katiyar
Kunal Katiyar

Reputation: 404

SwiftUI run function when app has been terminated and then opened

I recently learned how to run code whenever my app is opened by using onReceive and onAppear, as well as scenePhase. These work perfectly when the app is still in the background. However, when I terminate the app by swiping out of it after double tapping Home, and then open it, none of them work. How do I make the code run whenever the app is opened, even if it is not in the background?

Here is my code for on-open functions:

.onChange(of: scenePhase) { newScenePhase in
        switch newScenePhase {
         case .active:
          //open QR Scanner when app is resumed
          print("Active")
          return
        case .background:
          print("Background")
         return
        case .inactive:
            print("Inactive")
        @unknown default:
         return
         }
        }

.onAppear {
                print("opened!")
            }
            .onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
                print("opened! 2")
            }
            .onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in
                print("opened! 3")
                
            }

Upvotes: 1

Views: 2053

Answers (1)

jnpdx
jnpdx

Reputation: 52312

This code has two different options for running code that will only run when the app is launched (eg "swiped out and then opened again").

Keep in mind that you will not see the printed lines in the debugger the second time as the debugger will not be attached to the new instance -- Xcode only attaches to the first instance that you run.

@objc class AppDelegate: NSObject, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        print("launch")
        return true
    }

}

@main
struct MyApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    init() {
        print("App runs")
    }
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

Since the debugger console won't show the prints on the second launch, here's an example proving that the init code runs that you can see in the UI:

@main
struct MyApp: App {
    var appState = AppState()
    
    init() {
        print("App runs")
        appState.count += 1
    }
    
    var body: some Scene {
        WindowGroup {
            ContentView(appState: appState)
        }
    }
}

class AppState : ObservableObject {
    @Published var count = 0
}

struct ContentView : View {
    @ObservedObject var appState : AppState
    
    var body: some View {
        Text("Hello: \(appState.count)")
    }
}

Upvotes: 2

Related Questions