SwiftUI: répondez à l'arrêt de l'application sur macOS

Nov 21 2020

Je crée une application multiplateforme avec SwiftUI 2.0. Le cycle de vie de l'application est géré par SwiftUI, il n'y a donc pas d'application ou de délégué de scène. Si possible, j'aimerais qu'il en soit ainsi. Afin de conserver les données lorsque l'application se ferme ou entre en arrière-plan, je suis à l'affût des modifications 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
                }
        }
    }
}

Cependant, cette approche présente un défaut inhérent: sur macOS, lorsque l'application est arrêtée, il n'y a pas de changement scenePhaseet les données ne sont donc pas persistantes. Existe-t-il un mécanisme distinct pour détecter la résiliation d'application? SwiftUI a-t-il l'équivalent de applicationWillTerminate:?

Réponses

1 Asperi Nov 21 2020 at 07:42

Vous pouvez injecter un délégué d'application via l'adaptateur. Utilisez comme exemple suivant:

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