'best practice handling NSManagedObjects and CoreData in multiple VC's

i'd could use your advice on this one

i restructured my whole app, to use coreData so i'd be able to save the Main Class of my app: "FooBar" i also transfered my complete business logic into that NSManagedObject subclass FooBar() that's why i needed to to use some kind of convenience init, to start my own methods for calculating values and so on here's my class definition:

Import Foundation
import CoreData
import UIKit

@objc(FooBar)
public class FooBar: NSManagedObject {
    
    var context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext // used for other CD interactions inside this class
    var member1 = Int()
    var member2 = Double()
    var member3:Double = 0
    var fooPack:[FooPacks] = []
    ...
    
    
    convenience init(   param1: Int16
                     ,  param2: String?
                     ,  param3: Float
                     ,  param4: String?
                     ,  param5: Float
                     ,  fooPack: NSSet
                     ,  entity: NSEntityDescription
                     ,  context: NSManagedObjectContext?
                    ) {
        self.init(entity: entity, insertInto: context)
    
        self.param1 = param1
        self.param2 = param2
        self.param3 = param3
        self.param4 = param4
        self.param5 = param5
        self.addToUsedfooBarPacks(fooBarPack)
        
        self.build()
    }
    
    func build() {
        // i do something
    }
    
    func method1() {
        // i do something
    }

when i initialize my FooBar class inside a viewController i do this by:

self.fooBar = FooBar.init(param1: var1,
                              param2: var2,
                              iparam3: var3,
                              param4: var4,
                              param5: var5,
                              fooPack: var6,
                              entity: FooEntity,
                              context: context)

when ever i modify any instance of this class i do this by:

self.fooBar.member2 = newValue
self.fooBar.build()

and later at a specific point (in multiple VC's) i then call to save that Instance to CoreData:

let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
do {
        try context.save()
    }catch{
        print("\(error)")
    }

with this approach i often have to deal with bugs and unexpected behaviours like: the do block gets executed successfully, but the object has NOT been saved!?

i often hand over FooBar instances to a different ViewController and i try to save them there, but this does not seem to be the right way to do update previous fetched objects

in my opinion, this has to do with the way i handle the context variables.. and exactly this is why i am reaching out for your advice..

What is the optimal way to handle such a situation, where i want to modify and save instances within multiple different ViewControllers? i already learned a lot new stuff about CoreData in the last months, but i seem to miss something important here..

please help me out guys :)



Solution 1:[1]

You're using persistentContainer, it helps you setup coredata stack. persistentContainer has two types of context: viewContext and background contexts

With this setup we always use viewContext to fetch data to display on UI. And use a background context to make changes, update storage...

  1. What is the kind of context you passed in init method?
  2. You should execute context.save() on exactly the context that you used to make changes (you passed to init). In this case you shouldn't pass viewContext to init and use viewContext to call save()
  3. How to update and sync changes between multiple ViewControllers? The view controller that makes changes should call save as well. And you can use delegation pattern to delegate/broadcast changes to other view controllers...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 nghiahoang