5
votes

I took a break from coding for a few months and came back and discovered the changes in CoreData with Xcode8/iOS10/macOS Sierra.

I have been trying to get my head around the new NSManagedObject subclass generation in Objective C but there is very little out there on the web. I have a few things I need clarifying before I start butchering my project and messing things up completely but first, some things I have discovered from poking around that might be useful to others out there...

Where things are

Automatically generated files live buried deep in the DerivedData folder. Look in USER->Library->Developer->Xcode->DerivedData->ProjectName-lotsOfRandomLetters->Build then keep opening folders until you find DerivedSources->CoreDataGenerated.

Automatically generated files do not appear in your project folder or navigator, although if there is an error in one Xcode will display the source for you.

Things Xcode generates

There are three codegen settings - manual/none, Class Definition, and Category/Extension.

When an entities codegen is set to manual/none (which was the old behaviour) creating the NSmanagedObject subclass using Editor-> Create NSManagedObject Subclass generates 4 files inside your project...

Entity+CoreDataClass.h and Entity+CoreDataClass.m and Entity+CoreDataProperties.h and Entity+CoreDataProperties.m

(previous version Xcode 7 generated Entity.h, Entity.m, Entity+CoreDataProperties.h and Entity+CoreDataProperties.m files)

If the entity's codegen is set to Class Definition, Xcode generates these same 4 files automatically in the derived data folder - not the project, These files are then marked with a comment telling you not to alter them.

Xcode generates 2 files if the entities codegen is set to Category/Extension. These files are marked with a comment telling you not to alter them. These are...

Entity+CoreDataProperties.h and Entity+CoreDataProperties.m

These 2 file are expecting a Entity.h file to be in the project and will show an error in Xcode if absent. This is the one time that you will be able to see the source for one of these files within Xcode.

Whats in these files

The + CoreDataProperties files appear to be the same as those generated previous version of Xcode generated files except for one addition. They contain all the attributes / properties for the entity / NSmanagedObject and the methods to handle entities that have a one to many or many to many relationship. The new addition is a method for fetchRequest subclassing NSmanageObject's new fetchRequest method.

Questions

1) Is Class Definition now the obvious and best choice for codegen when you don't have any extra properties/functionality to add to a NSManagedObject subclass, as it automatically updates the files for you (when you save the project with cmd-s)?

2) The naming of the files with +CoreDataClass follows the convention for a category on a class, which would imply there should be a class for this to be an extension on.

Am I right in assuming that the Entity+CoreDateClass .h/m files are a straight replacement for the old Entity.h/m files? and that its not actually a category, despite the file name?

3) For new NSManagedObject subclasses should I be importing Entity+CoreDataClass.h rather than Entity.h?

4) If I want to uncluttered my project by removing most of my NSManagedObject subclass files, do i just delete the files in Xcode and set the entities codegen to Class Definition or ...

is there magic under the hood that looks for the entity+CoreDataClass when you try to #import entity.h or will I have to go through and find every reference to #import entity.h and change them to #import entity+CoreDataClass.h ?

5) Am I right in assuming that if I want a NSManagedObject subclass where I want to add a property and a method that i should set codegen to Category/Extension?

6) If I choose Category/Extension I have to create my own NSmanagedObject subclass file, its just entity.h not entity+CoreDataClass.h?

7) If entity+CoreDataClass.h is the new accepted naming format for the entity.h file why does the generated Category/Extension file look for a plain entity.h name file instead of a entity+CoreDataClass.h file? Is this just an inconsistency on Apples part and something I should just accept or am I missing something that I should know about?

Thank you.

1
Find some of the answers plus a link to the corresponding WWDC video here.shallowThought

1 Answers

3
votes

Okay - quite a few people looked and no answers so i'll try and answer myself.

1) Yes - if you don't need to add extra properties/functionality to a CoreData entity, go with Class Definition. This creates 4 files: Entity+CoreDataClass.h and Entity+CoreDataClass.m and Entity+CoreDataProperties.h and Entity+CoreDataProperties.m but you'll never see them as they are hidden away from sight deep inside the derived data folder. If you need to check on a attribute name you can look in the core data editor as you won't have access to these files.

2) Entity+CoreDateClass .h/m files are a straight replacement for the old Entity.h/m files. Despite using the file naming convention for a category, they are not categories, don't let Apple's naming system confuse you. Look inside the file and the class is defined as Entity not Entity+CoreDataClass.

3) For new NSManagedObject subclasses (autogenerated with the 'Class Definition' option) import Entity+CoreDataClass.h rather than Entity.h. After all' it's the file you are importing not the class defined inside. When using the class its just Entity not Entity+...

4) If you decided to declutter your project, by deleting your NSManagedObject subclass files then switching entities codegen to 'Class Definition', you will need to go through the project and change all the import statements that refer to them by adding +CoreDataClass to the file name. Fortunately its not that big a deal as Xcode will have flagged them all up as errors anyway so they are easy to find.

5) Yes - if you wish to add properties or functionality to a NSManagedObject subclass use the codegen "Category/Extension" option.

6) If you choose Category/Extension you have to create my own NSmanagedObject subclass file, name it Entity.h. Do NOT name it Entity+CoreDataClass.h because the autogenerated Entity+CoreDataProperty.h is looking to import an Entity.h file.

7) Yes, this is just a naming inconsistency on Apple's part. Don't let it throw you, like it did me.

And finally , don't forget...

if you go down the route of using codegen ->Category/Extension, if you add an additional relationship to the entity, you will need to update your Entity.h file. For example if you added a relationship to a NSManagedObject subclass called Car you would need to add the @Class Car; to Entity.h.