user1904273
user1904273

Reputation: 4764

ios/xcode: Best place for Core Data properties and methods

I have followed various core data tutorials and they all seem to recommend different places to put the core data code, i.e. properties and methods for the nsmanagedobject, nsmanagedobjectcotext and nspersistent store coordinator.

In the Xcode sample project they put it in app delegate.

Based on the MVC pattern, others recommend putting all the data and logic in a separate data class like Model or Item. However, this does not seem advisable if you are using the editor to automatically generate a class for each entity or table in the data model as each time you did this you would overwrite the core data properties and methods

Another option I have seen is to put it in the view controller. But this does not seem to be a good example of MVC.

Surely there must be a best practice for this. Would appreciate guidance on this point as I am building an app and don't want to have to redo this important step.

Thank you.

Upvotes: 1

Views: 1181

Answers (3)

Michał Ciuba
Michał Ciuba

Reputation: 7944

Using one Model class for the whole logic is a terrible idea as it quickly can become a God Object.

You can add additional methods in categories on NSManagedObject subclasses, so that they won't be overwritten after re-generating classes. This would work for simple tasks, like validating data(there are even built-in methods for that purpose in NSManagedObject), or simple filtering of to-many relationships (like getting the events from the last week in a Calendar entity). After all, NSManagedObjects are objects and objects are able not only to store data, but also to do things. I have successfully used this approach for an application having ~50 entities.

For more complex tasks, you can create plain NSObject subclasses which work with managed objects. For example, in my app I used MessageSynchronizer class which was dealing with Message entity instances, responsible for synchronizing messages with the web service (it wasn't hitting the network, just handling possible conflicts between local and remote data). For tasks related to displaying data (like formatting dates), you can use Model-View-ViewModel pattern and do them in ViewModels. Just remember about essential OOP principles, like Single Responsibility Principle.

Upvotes: 2

Tom Harrington
Tom Harrington

Reputation: 70956

It sounds like you're mixing up a couple of different things.

Xcode's project templates put code to handle NSPersistentStoreCoordinator and NSManagedObjectContext into the app delegate. This is not terrible but not great either, and lots of other examples recommend putting it somewhere else-- for example, some kind of Core Data manager class.

That code does not handle properties or custom methods on NSManagedObject instances. Those typically go into subclasses of NSManagedObject. If you use Xcode to generate these subclasses, you're right, Xcode will lose existing code if you redo the process. It's convenient but brittle. A better approach is to use mogenerator, an open source tool for generating subclasses. It creates two subclasses for each entity. You put your custom code in one and leave the other alone. If you ever re-generate the files, the one with your custom code doesn't get overwritten.

Upvotes: 1

Olaf
Olaf

Reputation: 3042

Put logic into a Model class, for example the methods for the NSManagedObjectContext and NSPersistentStoreCcoordinator. This class can inherit from NSObject.

Create (if needed) classes for the NSManagedObjects. My recommendation is to keep as much logic outside your entity classes. It is tempting to add logic into the entity class to react to attribute values (or changes). But when evaluating this approach consider that your NSManagedObject is rather short lived. Don't pass it around inside your app. The NSManagedObject can be turned into a fault and your logic won't be reachable anymore.

Consider moving logic into a separate class that does not inherit from NSManagedObject. This could be your Model class. Perform the required logic inside that Model class. That class won't fault on you and you'll have more liberties with the contexts.

Then: Do not let Xcode recreate your class files. After making changes to the model update manually the NSManagedObject class file. An update to the class file should only be needed when the type or the name of an attribute changes.

This manual procedure does need a bit of discipline but is much easier to maintain and administer than any category or extensions of the model class.

Upvotes: 1

Related Questions