In my app, I have a special CoreDataManager class that is responsible for all Core Data operations in my app.
The first lines in CoreDataManager Class look like this:
static var sharedInstance: CoreDataManager = { // or private static var
let instance = CoreDataManager()
return instance
}()
// Init
override init() {
self.persistentContainer = NSPersistentContainer.init(name: "AppName")
self.persistentContainer.loadPersistentStores { (storeDescription, error) in
if let error = error as NSError? {
fatalError("CoreDataManager: init, loadPersistentStores error: \(error), \(error.userInfo)")
} else {
print("CoreDataManager: init() func finished with Success!")
}
}
self.persistentContainer.viewContext.undoManager = nil
self.persistentContainer.viewContext.shouldDeleteInaccessibleFaults = true
self.persistentContainer.viewContext.automaticallyMergesChangesFromParent = true
}
let persistentContainer: NSPersistentContainer
var viewContext: NSManagedObjectContext? {
return self.persistentContainer.viewContext
}
func saveViewContext() {
let context = self.viewContext
if self.viewContext != nil {
if context!.hasChanges {
do {
try context!.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
When I need to save, edit or delete core data entities in my app I call a singleton of CoreDataManager class, and methods of (saving, editing, deletion of entities) declared in this class.
In my app I also have a LocalNotificationManager, where I do some operations with CoreData
entities when I receive changes from CloudKit
or when I delete some entities. I'm calling CoreDataManager.sharedInstance.saveViewContext()
when I want to save changes, and " think that I'm doing it wrong because sometimes I get errors.
I don't clearly understand how to properly call context and save it, and have the following questions:
In my save, edit, delete calls, should I use/save mainContext or privateContext?
When notifications received, should I use/save mainContext or privateContext?
When I should save viewContext from the main thread, and when to use private managed object context? Should I use .MainQueueConcurrencyType or I can avoid it?
Should I declare a privateObjectContext variable in my CoreDataManager class and which is the proper way to do this?
I've seen that private context can be declared this way, but can I implement it in my CoreDataManager class and when should I call it instead of saveViewContext()
.
let moc = NSManagedObjectContext(concurrencyType:.MainQueueConcurrencyType)
let privateMOC = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
privateMOC.parentContext = moc
privateMOC.performBlock({
do {
try privateMOC.save()
} catch {
fatalError("Failure to save context: \(error)")
}
})
Can anyone explain the proper usage of saving context in different situations clearly, please?
Swift 4, Xcode 9.