georgeok
georgeok

Reputation: 5696

swiftUI detect app termination while in background

I have an application that runs in the background capturing the user's location using CoreLocation. I want to save the data when the app is closed by the user.

When the app goes to the background, I can use the scenePhase, but how to detect that the application will be terminated when it's running in the background?

import SwiftUI

@main
struct myApp: App {
    @Environment(\.scenePhase) var scenePhase

    var body: some Scene {
        WindowGroup {
            ContentView()
                .onChange(of: scenePhase, perform: { phase in
                    print(scenePhase)
                })
        }
    }
}

this prints:

inactive
background

I have also tried the NotificationCenter

NotificationCenter.default.addObserver(
    forName: UIApplication.willTerminateNotification,
    object: nil,
    queue: .main) 
{ _ in
    print("terminated")
}

and this is also not called when the app is already in the background.

Upvotes: 2

Views: 2484

Answers (2)

Mark Krenek
Mark Krenek

Reputation: 4947

From the documentation for applicationWillTerminate:

For apps that support background execution, this method is generally not called when the user quits the app because the app simply moves to the background in that case.

And from https://developer.apple.com/documentation/uikit/app_and_environment/scenes/preparing_your_ui_to_run_in_the_background:

Use deactivation to preserve the user’s data and put your app in a quiet state by pausing all major work; specifically: Save user data to disk and close any open files.

Basically, when your app is deactivated and backgrounded, you won’t know if the app eventually gets terminated, so you probably need to use the deactivation/backgrounding to do your work, if that makes sense in your use case. Can you save the user data every time you get a location event in the background?

Upvotes: 1

DarkSatyr
DarkSatyr

Reputation: 160

Try - (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions;

Upvotes: 1

Related Questions