Core Data and Swift Package Manager

Dmytro Anokhin
Aug 14, 2019 · 2 min read

Swift Package Manager smoothly integrates with the workflow in Xcode 11, but comes with one small limitation: we can not bundle resources with Swift packages. For Core Data this means that we can not include model files.

The solution is to create Core Data model programmatically. Let’s see how we can do this and the process can be improved.

TL;DR; I encountered this problem when I decided to create the index of downloaded images for my URLImage package. I came up with declarative approach and created a separate Swift package: CoreDataModelDescription to describe the model in code.

Core Data model in code

Core Data provides classes to describe the model in code, here are some:

  • NSEntityDescription describes an entity in a model: name, list of properties, and NSManagedObject class.
  • NSPropertyDescription describes a property of an entity: name, is it transient, is it optional. Property is a base for attributes and relationships.
  • NSAttributeDescription allows to specify a type, default value, and other features of an attribute in an entity.
  • NSRelationshipDescription describes relationships between two entities.

Both attribute and relationship are properties of an entity. There are more descriptions for sophisticated models. Consider this as minimum required to create feasible Core Data model.

Let’s take a simple model like this:

Model file (.xcdatamodeld) is a package and model is actually described in XML:

We can follow it to describe the model in code. This routine by steps:

  • Create NSEntityDescription objects and establish sub-super entity connections between them.
  • Create NSAttributeDescription for the fields that store data in your model.
  • Create NSRelationshipDescriptions. Establish inverse relationships.
  • Fill properties on the entities with attributes and relationships.

NSManagedModel can be created like this:

For the reference this is how NSManagedObject subclasses look like:

As you can see the process is not hard but describing a model takes a lot of code. This is a good example of declarative (XML) vs imperative approaches.

Describing Core Data model in code

It’s a shame not to try declarative approach in code to solve the problem. Here is what I came up with:

I really like how Swift Package Manager uses Package.swift file to describe a package so I decided to follow its format.

Describing Core Data mode declaratively feels natural and allows to focus on the model itself.

CoreDataModelDescription is available as a Swift package. Give it a try.

Cheers!

Dmytro Anokhin

Written by

iOS Developer, here to share best practices learned through my experience. You can find me on Twitter: https://twitter.com/dmytroanokhin

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade