SwiftUI: reaguj na zamknięcie aplikacji w systemie macOS

Nov 21 2020

Tworzę aplikację wieloplatformową z SwiftUI 2.0. Cykl życia aplikacji jest zarządzany przez SwiftUI, więc nie ma delegata aplikacji ani sceny. Jeśli to możliwe, chciałbym, żeby tak zostało. Aby zachować dane, gdy aplikacja zamyka się lub wchodzi w tło, czekam na zmiany 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
                }
        }
    }
}

Jednak takie podejście ma nieodłączną wadę: w systemie macOS, gdy aplikacja zostanie zakończona, nie ma żadnych zmian scenePhase, a zatem dane nie są utrwalane. Czy istnieje oddzielny mechanizm wykrywania zamykania aplikacji? Czy SwiftUI ma odpowiednik applicationWillTerminate:?

Odpowiedzi

1 Asperi Nov 21 2020 at 07:42

Możesz wstrzyknąć delegata aplikacji za pośrednictwem adaptera. Użyj jako następującego przykładu:

#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
}