StorageKit: What, How and What’s next

StorageKit?

We tried to explain what StorageKit is here:

StorageKit is a framework that reduces the complexity of managing a persistent layer. You can easily manage your favorite persistent framework (Core Data / Realm at the moment), accessing them through a high-level interface.
Our mission is keeping the persistence layer isolated as much as possible from the client codebase. In this way, you can just focus on developing your app. Moreover, you can migrate to another persistent framework easily, keeping the same interface: StorageKit will do almost everything for you.

The idea is to take off the persistency complexity in order to let you focusing on what you have to develop.

What you can do is to instantiate you favourited storage in this way

and the you can use the storage to perform CRUD operations over the persistency layer through its main context:

That’s it! 🎉

Core Data and Realm: try to pick the best from both

The first reason why StorageKit was born is because me and Marco wanted to create a unified API over specifically Core Data and Realm.

During the design phase we considered that both frameworks rely on subclasses of core objects as NSManagedObject and Object to manage and persist data.

Instead of creating another layer over these two core objects we decided to provide a protocol called StorageEntityType and within StorageKit we have extended both NSManagedObject and Object in this way:

This means that who uses StorageKit will implement their entities as NSManagedObject or Object subclasses, passing them to StorageKit without changing anything else. Every method included or exposed by the framework expect a StorageEntityType.

With this approach, StorageKit could be applied to legacy projects without any extra work over the existing entities; on the opposite side, these are direct dependencies over Core Data/Realm not hidden by StorageKit, this means that you still should know something about them ☺

Internal Architecture

The storage protocol is the foundation of the StorageKit framework and it exposes the mainContext which is the object used to perform CRUD operations over the chosen persistency layer.

We tried to implement this core with SOLID in mind to have well isolated components within the framework itself and to create a core easily pluggable (well in the next future we hope to add new frameworks quite easily!).

So, going back to the code, once you get a storage, you can perform queries using its mainContext in this way:

An important concept here is that the fetch method (as any other CRUD method in StorageKit) is a generic function defined as:

This means that when you call it, you must specify the type of the returned entities in the closure itself (lines 2 and 10 of the previous example!).

How background support works

When working with the persistence, you should care about avoiding to perform too many operations on the main thread (especially long writes). So we added the possibility to perform background queries with zero-configuration.

As I already described, the Storage protocol exposes only two methods and both are related to the background management:

The idea is that you work on a Storage that includes a main context, so when you want to perform background operations you have to implement something like this:

Let’s review what we have done here:

  1. call performBackgroundTask on the current Storage: it returns a background context which can be used to perform background operations;
  2. call an operation on that context (i.e. in this case fetch) and get the results;
  3. let’s say that you want to save the results on a different context, or you want to pass these entities to the Main Thread to update the UI, so you have to retrieve your objects on that context with getThreadSafeEntities;
  4. finally use the objects in the proper context (i.e. update the UI) 🎉

The follow snippet shows you the details of the backgroundTask implemented for both Core Data and Realm:

What’s next

This implementation has been quite tricky because we wanted to heavily rely on Swift Generics and our goal was to provide a easy to use API.

In our opinion the API is not so easy to use so the roadmap for the next future is this:

  1. decrease the number of callbacks: some callbacks are just style, they don’t provide any extra value to the user, so it’d be better to return values instead of using a completion handler to make the API cleaner;
  2. StorageKit now has a huge problem to be fixed as soon as possible: we have added support to Cocoapods and Carthage but there is no way to avoid installing the Realm Framework if you want to use StorageKit only on Core Data;
  3. Entities and system notifications are not managed through StorageKit, we’d like to include these within the architecture;
  4. The same for the migrations, now you have to manage them by yourself;

So, I think that StorageKit is a quite tricky and challenging project that could give to the community a good satisfaction 😊 We have to work hard to quickly move to the version 1.0 that should include big improvements, so any contribution would be really welcome 🤙🏼

Let us know what you think about StorageKit and if you want to help us please start the repo here and share it across the social things 🚀

You may also like

Leave a Reply

Your email address will not be published. Required fields are marked *