Reputation: 1678
I have created a separate CoreDataStack.swift object outside of the AppDelegate to follow much of the advice on here when working with CoreData. But how do I pass the MOC to the rootViewController in AppDelegate? Do I need to add code to the AppDelegate or to the ViewController? Thanks to anyone who can help me here in Swift as much of the older ObjC doesn't work for me!
my CoreDataStack includes the MOC
lazy var managedObjectContext: NSManagedObjectContext = {
let managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType) //
managedObjectContext.persistentStoreCoordinator = self.persistentStoreCoordinator
return managedObjectContext
}()
The AppDelegate has a method to create some data and in didFinishLaunchingWithOptions I can print to the console to see its working
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let fetchRequest = NSFetchRequest(entityName: "WordList")
do {
let results = try coreDataStack.managedObjectContext.executeFetchRequest(fetchRequest)
if results.count == 0 {
addTestData()
}
} catch {
fatalError("Error fetching data!")
}
do {
if let results = try coreDataStack.managedObjectContext.executeFetchRequest(fetchRequest) as? [NSManagedObject] { //cast to an array of NSManagedObject
for result in results {
if let listName = result.valueForKey("listName") as? String {
print("Got a '\(listName)'")
}
}
}
} catch {
print("There was a fetch error")
}
// WHAT CODE HERE WILL PASS THE MOC TO THE ROOT VC?
return true
}
I have a simple TableViewController embedded in a navigation controller
import UIKit
import CoreData
class WordListsTableViewController: UITableViewController {
var coreDataStack: CoreDataStack!
var wordLists = [WordList]()
override func viewDidLoad() {
super.viewDidLoad()
title = "Word Lists"
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: "viewWordList")
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
// DO I NEED CODE HERE TO CALL THE MOC?
reloadData()
tableView.reloadData()
}
func reloadData() {
let fetchRequest = NSFetchRequest(entityName: "WordList")
do {
if let results = try coreDataStack.managedObjectContext.executeFetchRequest(fetchRequest) as? [WordList] {
wordLists = results
}
} catch {
fatalError("There was an error fetching wordLists!")
}
}
Upvotes: 2
Views: 1540
Reputation: 4533
There are several ways to access managed object context. If you defined managedObjectContext
in the AppDelegate you can use:
let appDelegate = UIApplicationDelegate.sharedApplication().delegate as! AppDelegate
let managedObjectContext = appDelegate.managedObjectContext
managedObjectContext.doStuff()
The second way to pass managedObjectContext
through view controllers is to create an extension of UIViewController
.
extension UIViewController {
lazy var managedObjectContext: NSManagedObjectContext {
// Create core data stack or use singleton object
return coreDataStack.managedObjectContext
}
}
By doing this would be able to access managedObjectContext on each subclass of UIViewController
. Then you can write:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.managedObjectContext.doSomething()
}
By accessing managedObjectContext in any of these ways you are able to get managedObjectContext
in your rootViewController
and in any UIViewController
you create.
Upvotes: 2