SwiftUI: Reagieren Sie auf die Beendigung der App unter macOS

Nov 21 2020

Ich erstelle eine plattformübergreifende App mit SwiftUI 2.0. Der Lebenszyklus der App wird von SwiftUI verwaltet, sodass kein App- oder Szenendelegierter vorhanden ist. Wenn möglich, würde ich es gerne so halten. Um Daten zu erhalten, wenn die App beendet wird oder in den Hintergrund tritt, achte ich auf Änderungen an scenePhase.

@main
struct MyApp: App {
    
    @Environment(\.scenePhase) var scenePhase
    @StateObject var dataModel = DataModel()
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onChange(of: scenePhase) { newScenePhase in
                    switch newScenePhase {
                    case .background, .inactive:
                        dataModel.save()
                    default: break
                }
        }
    }
}

Dieser Ansatz weist jedoch einen inhärenten Fehler auf: Unter macOS gibt es beim Beenden der App keine Änderung scenePhase, und daher bleiben die Daten nicht erhalten. Gibt es einen separaten Mechanismus zum Erkennen der App-Beendigung? Hat SwiftUI das Äquivalent von applicationWillTerminate:?

Antworten

1 Asperi Nov 21 2020 at 07:42

Sie können den Anwendungsdelegierten über den Adapter injizieren. Verwenden Sie als folgendes Beispiel:

#if os(macOS)
class AppDelegate: NSObject, NSApplicationDelegate {

    func applicationWillTerminate(_ aNotification: Notification) {
        // Insert code here to tear down your application
    }
}
#endif

@main
struct MyApp: App {

#if os(macOS)
    @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
#endif

    // ... other code
}