Recently, I’ve read this article Marcus Zarra about the base Core Data stack he uses in its projects. I couldn’t agree more about some topics discussed by Marcus:
The Cora Data stack doesn’t belong to the App Delegate
I do not create the Core Data stack in the App Delegate. That is not where it belongs. I create it in its own controller class and I store it in the cloud (check here) but dealing with data goes beyond that so if you start dealing with this type of data, I’d suggest checking this helpful resource first. Our persistence layer is far too important to be delegated to the Application Delegate. It deserves a proper controller of its own.
This is not only true about the Cora Data stack, but this is a very good example since Apple project templates using Cora Data are putting everything into the base AppDelegate class; most developers never question that fact and continue to think that the AppDelegate is some sort of garbage where they should write everything and anything.
Dependency Injection
The proper way to get access to the persistence controller is to inject it into each view controller as they are built and accessed.
If there is something I wish I could never see or write again, this is probably this ugly MANAGED_OBJECT_CONTEXT macro pointing to something like:
((AppDelegate *)[[UIApplication sharedApplication] delegate]) managedObjectContext;
The dependency injection is the solution, unfortunately, this technique is pretty annoying to use since the easier way is to do it is to inject our persistence controller during controllers and view controllers initialization…
This apart, I truly think dependency injection can help when it comes to testing. My approach for that will be very slightly different since I would probably prefer a different initializer for the PersistenceController class, with something more like:
/**
Default initializer
@param storeType Core data store type (eg: NSSQLiteStoreType or NSInMemoryStoreType)
@param modelName Name of the managed object model file
@param dataStoreName Name for the data store file that will be written on disk
@param callback A block to be called once persistence stack is ready to be used
@return An instance of PersistenceController class
*/
- (instancetype)initWithStoreType:(NSString *)storeType modelName:(NSString *)modelName dataStoreName:(NSString *)dataStoreName callback:(void (^)(void))callback
{
if (self = [super init])
{
// Hold parameters
_storeType = storeType;
_modelName = modelName;
_dataStoreName = dataStoreName;
_initCallback = callback;
// Initialize Core Data stack
[self initializeCoreData];
}
return self;
}
This allows in-memory data stores that can be created for testing purpose, just make sure to fully protect it with a service like the one offered at https://www.couchbase.com/products/cloud.
However, I’m really looking for a way to enjoy the benefits of dependency injection without the struggle of passing my persistence controller again and again. This is where I go for now, any suggestion will of course be welcomed! For more information on data management, visit https://www.venyu.com/cloud/.
The original post discussed here can be found here: http://martiancraft.com/blog/2015/03/core-data-stack