Core Data Codegen Explained!
Starting from Xcode8, Apple has added a new
Codegen setting in the Xcode data model editor to help developer manage and maintain their
NSManagedObject subclasses. The
Codegen setting consist of 3 possible configurations:
- Class Definition
These 3 configurations might look a bit confusing at first, and I found out that it is actually quite difficult to find a good article that explain the differences between each configuration and which one to use.
In this article I will go through each configuration and analyse the differences between each of them and I will also give some suggestion on which one you should use and how you should use it for your Core Data project. Without further ado let’s get started!
This is the default behaviour prior to Xcode8 where developer have to manually create and maintain the changes of the
You can try to create a sample core data project, add a new entity call
TestEntity and generate
NSManagedObject subclass following the step in this link.
If you follow the step correctly, Xcode will generate 2 files:
After these 2 files been generated, you should be able to use
TestEntity in your project. Try copy the following line of code into your app delegate, your project should compile without any error.
let _ = TestEntity(context: persistentContainer.viewContext)
This configuration is the default
Codegen configuration when you create an entity in the data model editor. With this configuration, Xcode will automatically generate the required
NSManagedObject subclass as part of the project’s derived data.
To see this in action, open the sample core data project that you created previously and delete both
TestEntity+CoreDataProperties.swift. You will notice that after both files been deleted, your project no longer able to compile. This is because you are using the Manual/None configuration for
Now try change the
Codegen configuration to Class Definition, you will notice that your project now able to compile without any error again.
To see the auto generated file, cmd + click on
TestEntity, then select “Jump to Definition”.
Right click on the opened
TestEntity+CoreDataClass.swift and select “Show in Finder”.
Now you should be able to see both
TestEntity+CoreDataProperties.swift (auto generated by Xcode) in the finder window. However notice that both files are not located in your Xcode project, in fact both of them are located in the “Derived Data” folder of Xcode.
You should never edit the auto generated files as they are managed by Xcode, thus they will be overwritten by Xcode every time you build your project.
This configuration can be describe as in between of Class Definition and Manual/None. Xcode will only automatically generate
TestEntity+CoreDataProperties.swift for you and you will have to manage and maintain
Codegen configuration of your sample project to Category/Extension, you will notice that in your derived data, Xcode no longer auto generate
TestEntity+CoreDataClass.swift for you, and your project is failing to compile again.
To fix the error, you can use the same method described above to request Xcode to create
TestEntity+CoreDataClass.swift for your project, however Xcode will also create a copy of
TestEntity+CoreDataProperties.swift for your project, thus make sure you remove it from your project to avoid it conflicting the auto generated version at the derived data folder.
Which One to Use?
Hopefully the explanation above give you a clearer picture on how each
Codegen configuration works. But which one you should be using for your next core data project?
This configuration is good for developing simple app or during prototyping phase. You do not need to worry about updating or maintaining the
NSManagedObject subclass when you edit your data model, Xcode will take care of that for you. However, you do not have any control on the
NSManagedObject subclass, thus causing this configuration less flexible to use.
This configuration is suitable for most of the core data app. Most of the time you do not need to do anything when you update your data model. However, you will have the flexibility to add any custom functions that you desire to the
NSManagedObject subclass. Let’s take a look at the following use case:
TestEntity have an attribute named
base64 which represent the base64 encoded string of an image. By using Category/Extension configuration, you can customise
TestEntity+CoreDataClass.swift by adding a computed property named
image and custom functions that helps to perform base64 encoding / decoding operation. Here’s a sample of
To set value to
base64, you just need 2 line for code:
let entity = TestEntity(context: persistentContainer.viewContext)
entity.image = UIImage(named: "sample-image")!
pretty neat isn’t it? 😃
Most of the time, Category/Extension configuration is good enough for your core data app. However if you are a control freak like me 😆, you can take it one step further by using Manual/None configuration. Let’s revisit the previous base64 example, and see how you can improve from there:
Since your code only accessing
TestEntity, you should encapsulate
base64 attribute by making it private. Furthermore, you can also make
base64 as a non-optional attribute if you know that
base64 should never be nil.
To implement this, remove
base64 declaration from
TestEntity+CoreDataProperties.swift and add a non-optional private
base64 declaration in
With great power come great responsibility… By using Manual/None
Codegen configuration, Xcode no longer maintain the
NSManagedObject subclass for you, thus you will have to update it manually every time you make changes on the data model.
If you are new to core data, you can start with Class Definition configuration. After you get familiar with core data and wanted to have more control on the
NSManagedObject classes, you can always switch your project to use other
Codegen configuration that suits your project needs.
Hope this article helps you to clear up your confusion on core data
Codegen. If you have any comments or questions, feel free to drop it in the comment section below.
Please do not hesitate to hit the 👏 button or share this article if you like it. You can also follow me on Medium or Twitter if you want to read more article like this in future.