Bob
Bob

Reputation: 8714

Swift Core Data structure

I am starting with Core Data in Swift, and as I saw in many tutorials, everyone is using ManagedObjectContext only in AppDelegate.swift.

In my application I would like to use ManagedObjectContext in multiple views, so I would need some mechanism of sharing that object.

I thought that it would be a good approach to create a class that will manage ManagedObjectContext everywhere.

I am not sure is it possible that ManagedObjectContext and other Core data related objects are initialized with singleton and is this even a good approach? Or it is better that I transfer ManagedObjectContext between every view (which I can't understand why it would be better).

Do you have some advice / suggestion or good demo for usage of Core data?

Upvotes: 1

Views: 1024

Answers (2)

vadian
vadian

Reputation: 285069

There are basically three options:

  1. Pass the context from the application delegate object to the initial view controller and then further from source view controller to destination view controller respectively.

  2. Since the application delegate object is accessible from everywhere leave the Core Data stack – as suggested by the template – in AppDelegate and simply write

    let appDelegate = NSApplication.sharedApplication().delegate as! AppDelegate
    let managedObjectContext = appDelegate.managedObjectContext
    
  3. Move the whole Core Data stack into a separate class and use it as singleton

    class CoreDataManager: NSObject {
    
      class var sharedManager : CoreDataManager {
        struct Singleton {
          static let instance = CoreDataManager()
        }
        return Singleton.instance
      }
    
      // MARK: - Core Data stack
    
      lazy var managedObjectModel: NSManagedObjectModel = {
        // The managed object model for the application. This property is not optional. It is a fatal error for the application not to be able to find and load its model.
        let modelURL = NSBundle.mainBundle().URLForResource("MyModel", withExtension: "momd")!
        return NSManagedObjectModel(contentsOfURL: modelURL)!
      }()
    
    ...
    
      lazy var managedObjectContext: NSManagedObjectContext = {
    
    ...
    

    and call it with

    let managedObjectContext = CoreDataManager.sharedManager.managedObjectContext
    

Upvotes: 3

Aaron Rasmussen
Aaron Rasmussen

Reputation: 13316

This question has been asked many times on StackOverflow. You ask if you should pass the ManagedObjectContext from view to view. The official answer from Apple is yes:

When you create a view controller, you pass it the context it should use. You pass an existing context, or (in a situation where you want the new controller to manage a discrete set of edits) a new context that you create for it. It’s typically the responsibility of the application delegate to create a context to pass to the first view controller that’s displayed.

A view controller typically shouldn’t retrieve the context from a global object such as the application delegate—this makes the application architecture rigid. Neither should a view controller create a context for its own use (unless it’s a nested context). This may mean that operations performed using the controller’s context aren’t registered with other contexts, so different view controllers will have different perspectives on the data.

This is called dependency injection. Whether you choose to use it or not is up to you. Relying on the AppDelegate or creating a separate singleton to access the managedObjectContext makes your code more "rigid", as they say, and down the road it can cause problems.

That being said, lots of people use singletons for this kind of thing. It is temptingly easy and the costs aren't immediately apparent. In addition to the SO link that I posted above a Google search for "dependency injection" will explain the advantages better than I can in a few words here.

Upvotes: 3

Related Questions