|
| 1 | +// |
| 2 | +// AppDelegate.swift |
| 3 | +// XcodeCleaner |
| 4 | +// |
| 5 | +// Created by Kirill Pustovalov on 07.07.2020. |
| 6 | +// Copyright © 2020 Kirill Pustovalov. All rights reserved. |
| 7 | +// |
| 8 | + |
| 9 | +import Cocoa |
| 10 | +import SwiftUI |
| 11 | + |
| 12 | +@NSApplicationMain |
| 13 | +class AppDelegate: NSObject, NSApplicationDelegate { |
| 14 | + |
| 15 | + var window: NSWindow! |
| 16 | + |
| 17 | + |
| 18 | + func applicationDidFinishLaunching(_ aNotification: Notification) { |
| 19 | + // Create the SwiftUI view and set the context as the value for the managedObjectContext environment keyPath. |
| 20 | + // Add `@Environment(\.managedObjectContext)` in the views that will need the context. |
| 21 | + let viewModel = ViewModel() |
| 22 | + let contentView = ContentView().environment(\.managedObjectContext, persistentContainer.viewContext).environmentObject(viewModel) |
| 23 | + |
| 24 | + // Create the window and set the content view. |
| 25 | + window = NSWindow( |
| 26 | + contentRect: NSRect(x: 0, y: 0, width: 480, height: 300), |
| 27 | + styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView], |
| 28 | + backing: .buffered, defer: false) |
| 29 | + window.center() |
| 30 | + window.setFrameAutosaveName("Main Window") |
| 31 | + window.contentView = NSHostingView(rootView: contentView) |
| 32 | + window.makeKeyAndOrderFront(nil) |
| 33 | + } |
| 34 | + |
| 35 | + func applicationWillTerminate(_ aNotification: Notification) { |
| 36 | + // Insert code here to tear down your application |
| 37 | + } |
| 38 | + |
| 39 | + // MARK: - Core Data stack |
| 40 | + |
| 41 | + lazy var persistentContainer: NSPersistentContainer = { |
| 42 | + /* |
| 43 | + The persistent container for the application. This implementation |
| 44 | + creates and returns a container, having loaded the store for the |
| 45 | + application to it. This property is optional since there are legitimate |
| 46 | + error conditions that could cause the creation of the store to fail. |
| 47 | + */ |
| 48 | + let container = NSPersistentContainer(name: "XcodeCleaner") |
| 49 | + container.loadPersistentStores(completionHandler: { (storeDescription, error) in |
| 50 | + if let error = error { |
| 51 | + // Replace this implementation with code to handle the error appropriately. |
| 52 | + // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. |
| 53 | + |
| 54 | + /* |
| 55 | + Typical reasons for an error here include: |
| 56 | + * The parent directory does not exist, cannot be created, or disallows writing. |
| 57 | + * The persistent store is not accessible, due to permissions or data protection when the device is locked. |
| 58 | + * The device is out of space. |
| 59 | + * The store could not be migrated to the current model version. |
| 60 | + Check the error message to determine what the actual problem was. |
| 61 | + */ |
| 62 | + fatalError("Unresolved error \(error)") |
| 63 | + } |
| 64 | + }) |
| 65 | + return container |
| 66 | + }() |
| 67 | + |
| 68 | + // MARK: - Core Data Saving and Undo support |
| 69 | + |
| 70 | + @IBAction func saveAction(_ sender: AnyObject?) { |
| 71 | + // Performs the save action for the application, which is to send the save: message to the application's managed object context. Any encountered errors are presented to the user. |
| 72 | + let context = persistentContainer.viewContext |
| 73 | + |
| 74 | + if !context.commitEditing() { |
| 75 | + NSLog("\(NSStringFromClass(type(of: self))) unable to commit editing before saving") |
| 76 | + } |
| 77 | + if context.hasChanges { |
| 78 | + do { |
| 79 | + try context.save() |
| 80 | + } catch { |
| 81 | + // Customize this code block to include application-specific recovery steps. |
| 82 | + let nserror = error as NSError |
| 83 | + NSApplication.shared.presentError(nserror) |
| 84 | + } |
| 85 | + } |
| 86 | + } |
| 87 | + |
| 88 | + func windowWillReturnUndoManager(window: NSWindow) -> UndoManager? { |
| 89 | + // Returns the NSUndoManager for the application. In this case, the manager returned is that of the managed object context for the application. |
| 90 | + return persistentContainer.viewContext.undoManager |
| 91 | + } |
| 92 | + |
| 93 | + func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply { |
| 94 | + // Save changes in the application's managed object context before the application terminates. |
| 95 | + let context = persistentContainer.viewContext |
| 96 | + |
| 97 | + if !context.commitEditing() { |
| 98 | + NSLog("\(NSStringFromClass(type(of: self))) unable to commit editing to terminate") |
| 99 | + return .terminateCancel |
| 100 | + } |
| 101 | + |
| 102 | + if !context.hasChanges { |
| 103 | + return .terminateNow |
| 104 | + } |
| 105 | + |
| 106 | + do { |
| 107 | + try context.save() |
| 108 | + } catch { |
| 109 | + let nserror = error as NSError |
| 110 | + |
| 111 | + // Customize this code block to include application-specific recovery steps. |
| 112 | + let result = sender.presentError(nserror) |
| 113 | + if (result) { |
| 114 | + return .terminateCancel |
| 115 | + } |
| 116 | + |
| 117 | + let question = NSLocalizedString("Could not save changes while quitting. Quit anyway?", comment: "Quit without saves error question message") |
| 118 | + let info = NSLocalizedString("Quitting now will lose any changes you have made since the last successful save", comment: "Quit without saves error question info"); |
| 119 | + let quitButton = NSLocalizedString("Quit anyway", comment: "Quit anyway button title") |
| 120 | + let cancelButton = NSLocalizedString("Cancel", comment: "Cancel button title") |
| 121 | + let alert = NSAlert() |
| 122 | + alert.messageText = question |
| 123 | + alert.informativeText = info |
| 124 | + alert.addButton(withTitle: quitButton) |
| 125 | + alert.addButton(withTitle: cancelButton) |
| 126 | + |
| 127 | + let answer = alert.runModal() |
| 128 | + if answer == .alertSecondButtonReturn { |
| 129 | + return .terminateCancel |
| 130 | + } |
| 131 | + } |
| 132 | + // If we got here, it is time to quit. |
| 133 | + return .terminateNow |
| 134 | + } |
| 135 | + |
| 136 | +} |
| 137 | + |
0 commit comments