Creating an abstraction layer for the model

Why another model?

I’m using Core Data to store the data in our app Remember. To create a Core Data model, I need to inject a NSManagedObjectContext object in the NSManagedObject constructor. The problem is I don’t want to have to pass around the context object everywhere in the app. I want it to be isolated in the model layer. And I want to manipulate simple POSOs (Plain Old Swift Object) in the business layer.

Also, my database objects should not know my business objects. By doing so, I could easily replace Core Data with another database provider, without impacting the rest of the codebase. This idea is inspired by the Clean Architecture.

Business and model layers

In our app Remember, I only have one table to store the last times a user did something. Pretty simple.

I created an Event class in my business layer. This is the object I will manipulate in the views.

For the model layer, I created an EventManagedObject class, which inherits from NSManagedObject.

To convert the objects in both directions, I created an ObjectConvertible protocol, implemented by the Event class.

Thanks to the protocol extension, I have only two methods left to implement. Those are the methods that transfer the business object’s data to the database object’s data and vice versa.

It is now super easy to perform operations on the Event object, without manipulating NSManagedObject objects directly.

At the beginning of this article, I said I didn’t want to have to pass a NSManagedObjectContext object throughout the code.

To isolate the context, I created an EventStore class, which keeps a reference on the NSManagedObjectContext object.


Even though this method provides some comfort when working with model objects, it has some downsides.

The biggest one is I can’t use Core Data’s built-in lazy-loading system or NSFetchedResultsController. If I wanted to use it, I would have to create my own pagination system.

Dealing with relationships is also not implemented in this solution. Even though I didn’t investigate it, the conversion of the nested objects would probably be in the from(object: T) and toObject() -> T implementation methods.

Final thoughts

I managed to do what I initially wanted, the Event class is totally agnostic of the EventManagedObject class.

I’m manipulating simple objects in the views.

And the model layer is isolated from the rest of the application. I could definitely replace Core Data with another database provider, without impacting the rest of the codebase.

The only thing left is to handle Core Data errors. Something I will definitely do in the app.

I honestly never worked on an app that had an abstraction layer for the model. As I said, it’s not common in the iOS world, from my experience at least. But I’m super happy with the result and I will definitely use it in my side project Remember.

Any feedback is welcome!

A big thank you to Ayrton for his help.