简体   繁体   中英

How to pass the ManagedObjectContext to the root view controller in swift

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!")
    }
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM