Core Data is Apple’s object persistent framework. It’s very powerful and thus can be complicated. This post is a list of tips(/battle scars) that have helped me tame Core Data. (When I find time I’ll add more details.)
Modelling
Include a root object.
Make the graph highly connected.
Avoid “pragmatic” inheritance, use only semantic inheritance.
Create bi-directional relationships but treat them as unidirectional (i.e. only set them on the ‘parent’ object).
Keep the model ‘pretty’. The modelling tool is very high level of abstraction. Use its spatial nature to document implicit relationships within the model.
Threading
Never delete an object which may be accessed in another context.
Never fault in an object which may have be deleted.
Only use objectID to pass a reference to objects between contexts.
Use assert to check threading.
OOP
Encapsulate NSManagedObjectContext - never expect a controller to directly operate on a MOC.
Use transformable properties.
Avoid treating managed objects as dumb data structures. Encapsulate fetches in class methods to add usage intent to the model.
Vend protocols rather than managed objects. Protocols allow polymorphism without inheritance and prevents controllers from setting properties that they shouldn’t.
Don’t make the model dependant on the presentation frameworks.
Don’t use the app delegate to create the Core Data stack.
Override accessors and Core Data life cycle methods to add asserts and check consistency.
Web services/Importing
Perform imports in a separate context.
Only perform 1 import background task.
Save responses to disk to aid debugging.
If import performance is sub-standard then use create-then-merge rather than fetch-then-create.
Take special care when merging relationships.
Hygiene
Don’t conflate authentication with domain knowledge.