Last active
March 17, 2021 11:35
-
-
Save ahbou/9565cad1f1ee353a7e3578168fa653ef to your computer and use it in GitHub Desktop.
CoreData discard changes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
class ProfileViewController: UIViewController { | |
/// First create a throwable child context for editing the Profile | |
private lazy var writeContext: NSManagedObjectContext = { | |
let result = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType) | |
result.automaticallyMergesChangesFromParent = true | |
result.performAndWait { | |
// Our main parent context | |
result.parent = DataSource.shared.mainContext | |
} | |
return result | |
}() | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
title = "My Profile" | |
// Let's add Cancel and Save buttons | |
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(promptToCancel(_:))) | |
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .save, target: self, action: #selector(save(_:))) | |
} | |
/// Present an alert asking the user to confirm discarding his changes | |
@objc func promptToCancel(_ sender: UIBarButtonItem?) { | |
guard writeContext.hasChanges else { | |
closeAndDiscard() | |
return | |
} | |
let alert = UIAlertController(title: "Do you want to leave and discard your changes?", message: nil, preferredStyle: .alert) | |
alert.addAction(UIAlertAction(title: "Stay", style: .default, handler: nil)) | |
alert.addAction(UIAlertAction(title: "Discard", style: .destructive) { [weak self] _ in | |
guard let self = self else { return } | |
self.closeAndDiscard() | |
}) | |
present(alert, animated: true, completion: nil) | |
} | |
// Cancel is confirmed: | |
private func closeAndDiscard() { | |
// Return our context to the previous state, | |
// by discarding all unsaved changes | |
writeContext.rollback() | |
dismiss(animated: true, completion: nil) | |
} | |
@objc func save(_ sender: UIBarButtonItem?) { | |
// No need to save if there are no changes | |
guard writeContext.hasChanges else { | |
dismiss(animated: true, completion: nil) | |
} | |
// Sync save our changes | |
writeContext.performAndWait { [weak self] in | |
guard let self = self else { return } | |
do { | |
try writeContext.save() | |
self.didSaveAndClose() | |
} catch { | |
print("failed to sync save \(error)") | |
// Show the error to the user | |
} | |
} | |
} | |
private func didSaveAndClose() { | |
// Parent context should be observing these | |
NotificationCenter.default.post(name: .NSManagedObjectContextDidSave, object: writeContext) | |
dismiss(animated: true, completion: nil) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment