Reputation: 1929
I am developing a Mac Application in Xcode 7.3.1. and I am trying to pass a Model Object Context from my AppDelegate to an ArrayController.
I have a class named DataController which creates my Core Data stack. DataController.managedObjectContext holds the Managed Object Context.
My AppDelegate class is as follows:
class AppDelegate: NSObject, NSApplicationDelegate {
var dataController: DataController!
func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application
// Create an instance of the DataController class.
dataController = DataController()
// Create a reference to the first ViewController embedded in the WindowController.
guard let splitViewController = NSApplication.sharedApplication().windows[0].contentViewController as? ManagedObjectContextSettable
else { fatalError("Wrong view controller type")}
// Set the managedObjectContext property.
splitViewController.managedObjectContext = dataController.managedObjectContext
}
func applicationWillTerminate(aNotification: NSNotification) {
// Insert code here to tear down your application
}
}
In my storyboard I have embedded a SplitViewController in my WindowController. The SplitViewController has its own custom View Controller class named SplitViewController. Here is the code in the SplitViewController:
class SplitViewController: NSSplitViewController, ManagedObjectContextSettable {
var managedObjectContext: NSManagedObjectContext!
override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
// Create a reference to the first ViewController embedded in the WindowController.
let childControllers = self.childViewControllers
print("childControllers.count = \(childControllers.count)")
for childController in childControllers{
if childController.isKindOfClass(TableViewController){
print("Found TableViewController")
guard let tableViewController = childController as? ManagedObjectContextSettable
else { fatalError("Wrong view controller type")}
tableViewController.managedObjectContext = managedObjectContext
}
}
}
}
Within one of the Split View Items is my TableView which has its own View Controller named TableViewController. Here is the code for TableViewController:
class TableViewController: NSViewController, ManagedObjectContextSettable, NSTableViewDataSource, NSTableViewDelegate {
@IBOutlet weak var tableView: NSTableView!
var managedObjectContext: NSManagedObjectContext!
override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
//print(managedObjectContext.description)
}
}
In the storyboard I dragged an ArrayController and in the Bindings tab of the Inspector I have set Bind To and selected TableViewController and set the Model Key Path to 'self.managedObjectContext'. Ultimately it's not receiving the Managed Object Context.
I cannot establish if I should override the prepareForSegue function for an embedded ViewController, every example I read is for IOS.
Where am I going wrong please?
Upvotes: 1
Views: 950
Reputation: 1929
This may not be good practice, but it appears to work.
I made my DataController class a singleton class to ensure there was only one Managed Object Context. In my TableViewController I created a managedObjectContext property as follows:
lazy var managedObjectContext = DataController.sharedInstance.managedObjectContext
In my array controller I bind the managed object context parameter to the TableViewController and set the Model Key Path to self.managedObjectContext.
Can this be improved upon?
Upvotes: 0
Reputation: 285082
If you are using an array controller with Cocoa bindings you have to override the init(coder:)
method and initialize the managed context there to perform the implicit initial fetch. viewDidLoad
is too late.
The segue workflow is the same as in iOS. It's even more convenient because there is a property presentingViewController
to get the reference to the parent view controller.
The Core Data Manager DataController
is supposed to be a singleton to ensure that the managed object context instance is always the same.
Upvotes: 0
Reputation: 15598
applicationDidFinishLaunching
can be executed after viewDidLoad
. Set managedObjectContext
of the childControllers when managedObjectContext
of the splitViewController is set.
Bindings use KVO. Change var managedObjectContext
to dynamic var managedObjectContext
to make the property KVO compliant.
Upvotes: 0