Chapter 2 v3.1 question about propagating

Hi all, I have a question and a little advice

about propagating a managed context in VC other than the main VC: should I implement a prepare for segue and pass it that way from the first view controller to the second one or should I build something like this in the app delegate?

    //book:
    guard let vc = window?.rootViewController as? ViewController else {
        return true
    }
    vc.managedContext = persistentContainer.viewContext

    //my test:
    guard let otherVC = window?.rootViewController as? OtherVC else {
        return true
    }
    otherVC.managedContext = persistentContainer.viewContext

more: in the ViewDidload of that second vc I wanted to do a test and put

 guard managedContext != nil else {return}
    
    
    do {
        try managedContext.save()
        print("managed context saved")
    } catch let error as NSError {
        print("could not save in did load \(error), \(error.userInfo)")
    }}

but I cannot see the context saved

regarding the advice:
the app you put in the example is great, but there is a lot of code you wrote about regarding the tabs of interface, that the help you gave delivering the boiler-code went away. a lot of time is wasted separating in my mind the parts that were really focused on the core data teaching progress of using the propagation and the subclassing of the entity. maybe using the same hitlist app and modify it in order to apply propagation and subclassing would make clear the lesson.

Your first code sample shows equivalent code, but changed names. Nothing wrong with that. As a first step you will have to pass the moc to the first view controller and that will achieve it in the app delegate as well as in prepare.

In the second sample you are saving as soon as a view controller is loaded? I think you will find that the viewDidLoad happens before you send the moc to the view controller. Try putting print statements in both the assignment, from app delegate, and in viewDidLoad in the target view controller.

If you need a save as soon as the moc is written then you could implement a setter and getter for the var:

var _moc : NSManagedObjectContext?
var moc: NSManagedObjectContext? {
    set {
        _moc = newValue
        do {
            try _moc.save()
            print("managed context saved")
        } catch let error as NSError {
            print("could not save in did load \(error), \(error.userInfo)")
        }
    }
    get {
        return _moc
    }
}

Apologies if there is a typo I did not compile this :slight_smile:

thanks for your reply!

the “//my test:” code in AppDelegate is a test to check if I understood the chapter; “OtherVC” in my example is a VC that is called when tapping a “add button” in the main VC and is used to add data to coreData. So here my points:

  1. having many VC in my app, is it right using app delegate in the way I’m using “// my test” for passing the MOC in each of them ? if I had 10 VC should I repeat 10 times the "//my test " in app delegate or is a waste of memory?

  2. is it better passing the MOC in the first VC then pass it only if needed in a prepare for segue?

  3. thanks for your code, but my check for saving MOC in ViewDidLoad (we are in the OtherVC) is not a need at now, it is just a try to see if I have successfully passed MOC itself in the var managedContext: NSManagedObjectContext! in pushed VC

here I’m trying to grab the proper way to get free from KVC, writing cleaner code and properly use coreData by subclassing entity.

It is funny there has been so much debate over the “right” way to do this when in many apps there are bigger issues to fix! I generally agree with people who say it is bad practise to have an app delegate method that returns the managed object context just because it leads to references to the app delegate and grabbing the moc being done anywhere and everywhere. Mostly I like to propagate the moc to the next view controller in line as shown, using prepare(for:sender:). But when a need for core data is several view controllers away from the app delegate and it leads to passing the moc through several view controllers that will never use it I am more inclined to just grab it from the app delegate. There are exceptions to every rule…

1 Like