Question

For my first IOS app I plan to incorporate CoreData however I'm a little unsure about the correct design pattern I should use.

In my app delegate I have the following 3 properties.

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;

I feel the best way to use these objects are to inject them into the constructor of all the relevant view controllers that need to access data from inside CoreData.

The cleanest way I can think of for that would be to create some kind of Repository class for each table I have in my data model which will house the above 3 objects and provide helper methods for accessing the tables data e.g. fetchAllTeams(). These repository classes can then be injected into the relevant view controllers instead of injecting all 3 objects above.

Does this sound like the correct thing to be doing in the world of CoreData & Objective-c?

Also whats the best way to create these repository classes, should I remove the default core data code and properties from the appDelegate (generated automatically) and place them inside an abstract repository class.

Should each instance of a repository have its own version of NSPersistentStoreCoordinator, NSManagedObjectModel and NSManagedObjectContext or should a single instance of these objects be shared among all repository instances passed in by the appDelegate.

Was it helpful?

Solution

Firstly, the base code that a Core-Data sets you up with can make the whole thing very confusing. The thing to understand is that Core-Data is a kind of wrapper around a variety of database technologies (sqlite, binary, xml) and by doing this, relieves you of the need to directly touch the database. The main class you are going to worry about in the beginning is NSManagedObjectContext. Think of it as a snapshot of the underling database which you can modify as you please and when you are done write that NSManagedObjectContext onto the database. The other classes you have there are really only needed for more fine-grained, low level control, and since this is your first app, best to leave those alone. You should read this, it is large, but you will gain a lot of understanding from it, especially how everything connects and their role.

To summarise though:

  • Really you only need to pass around the NSManagedObjectContext
  • You can do this my making an instance variable in every View Controller, OR,
  • You shouldn't go making more than one per app, unless you really need to, and then you need to make sure you merge them back together
  • You don't really need to create a repository of all the objects because NSManagedObjectContext does this for you...kinda... it will load objects into memory conditionally, there is a lot to this but the place to start is learning what a fault is (all in Apples documentation under NSManagedObjectContext or NSManagedObject)
  • think about what your objects represent and do. You can subclass NSManagedObject to represent your Core-Data object and place logic and validation inside of it - super handy.
  • Look into classes like NSFetchRequest and NSPredicate which are the two core classes for getting objects out of the NSManagedObjectContext.
  • Look into classes like NSFetchedResultsController which can tie very nicely into UI objects like UITableView.

Finally, Core-Data is a beast, and often you find yourself repeating common tasks all the time. You should look into this excellent framework which adds all sorts of helpers (like an easily accessible instance of NSManagedObjectContext, and one line object fetching, creating, deleting).

OTHER TIPS

With regards this bit, my two cents...

Also whats the best way to create these repository classes, should I remove the default core data code and properties from the appDelegate (generated automatically) and place them inside an abstract repository class.

I'd definitely take out all the code that Xcode generates from the app delegate and put its in its own class. This might be a good read in explaining the basic core data stuff: http://commandshift.co.uk/blog/2013/09/07/the-core-data-stack/ (via @jrturton).

Should each instance of a repository have its own version of NSPersistentStoreCoordinator, NSManagedObjectModel and NSManagedObjectContext or should a single instance of these objects be shared among all repository instances passed in by the appDelegate.

You typically only have one persistent store coordinator (another good post here on that).

You add models to the coordinator, and also persistent stores. You can have multiple managed object contexts on a coordinator if you like.

A good example is a master detail style structure, you have a table view controller (backed by a fetch results controller), this uses the shared instance of the managed object context. When selected a managed object in the table, you pass this object into your detail view controller when creating it. You don't need to pass through, or use the shared context as that managed object will have its own managedObjectContext.

You can even create further child contexts from this if you like - think of this as a temporary context, you can change any objects registered in this context, and if you change your mind and don't want the changes any more you can just ignore and not save the child context.

Unless you have no way of accessing a managed object, or are at the top of the stack you can use the shared context. Keeping the use of shared context to only when its needed, I personally think keeps things simpler as you don't have to worry about what's (and where) using the global shared context through out your app. (Granted the shared context will be the base one anyway, but using a managed objects own context will mean when you save any changes to that context you know that that object will be effected).

Also to deal with simpler accessing and creating of managed objects I recommend mogenerator, there's a good post here about setting it up.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top