
Relatively recently, I learned about
mogenerator , a wonderful command line application for generating classes based on the
Core Data object graph. And here's what, if you don’t know about him yet, then you should definitely get to know him, the use of this application greatly simplifies changing the Core Data object graph. mogenerator generates two classes per entity, one for machine use, the other for providing the possibility of adding additional functionality. Having correctly configured the project in Xcode, it is possible to generate this generation automatically before building.
In this article I will describe how you can use mogenerator with XCode 4 and some useful trivia.
As already described above, mogenerator generates two classes per entity, a total of four files. Let the entity be called Entity, the following files will be generated for such an entity:
- _Entity.h, _Entity.m - contain the _Entity class, these two files will be regenerated every time the Entity entity changes, after adding them to the project, you can forget about them,
- Entity.h, Entity.m - contains the class Entity, inherited from _Entity, these two files will be generated only once, they can be modified, they will not be overwritten.

The Entity class will be used in the code to represent the Entity entity and, best of all, the _Entity class will be synchronized with the data model! Once you set up mogenerator and add the generated files to the project, you can forget about updating the files, they will take care of this automatically.
Until I knew about the existence of mogenerator I used categories, I had the following files for the Entity entity:
- Entity.h, Entity.m - contain the class Entity, I regenerated these two files manually after changing the entity in the model,
- EntityEx.h, EntityEx.m - contain the Ex category for the Entity class, these two files I used to add functionality, in other files I connected EntityEx.h instead of Entity.h.

Of course, in many cases, this approach works perfectly, but I did not override the existing methods and almost did not use entity inheritance. In addition, as a result of any changes in the object graph, I had to generate classes for entities manually.
')
Setting up automatic file generation with mogenerator in XCode 4 (using the example of Xcode 4.6.2)
0. Of course you need to download and install
mogenerator .
1. Create scripts that will run mogenerator with the necessary parameters, the scripts that I use can be obtained
here . Sample script:
Pay attention to the last parameter: - template-var arc = true, thanks to it, the generated files will be compatible with ARC.
To define a base class other than NSManagedObject, use the --base-class parameter.
2. Now in Xcode, select the desired target, open the “Build Rules” tab, add two rules, one for the “Data model version files”:

, another for “Data model files”:

Do not forget to specify the line in the Output Files, without it, the scripts will not run at all (correct me if I'm wrong).
3. For each entity in the model, you must specify the correct class (usually coincides with the name of the entity):

Otherwise, mogenerator will skip entities and will not generate files for them.
4. Everything, now you can try to build a project (Build, command B)
To find out the result of the mogenerator, you can look at the Log Navigator and select the latest build:

On the image one of the problems that may occur:
"Print: Entry, "_XCCurrentVersionName", Does Not Exist"
This happens if no version has yet been added to the versioned data model, for example, you have just created it. I'm not sure if this is a big problem, but it is corrected by adding and removing (% Model% .xcdatamodeld "Show package contents", manually deleting .xcdatamodel or via the terminal, as convenient) of the version of the data model. After this removal, you must remove and add the .xcdatamodeld file to the project.
If everything is done correctly in the Log Navigator you can see something like the following:

5. The generated files themselves will not be added to the project, you need to do it yourself:

It is enough to connect the ModelIncludes.h file and in the right place all generated .h will be available. Once you add a newly-generated file to a project, you can forget about it, before each build the necessary files will be regenerated.
I have compiled a demonstration
project in which mogenerator is configured in the manner described.
Some useful little things
Transformable attributes
To store non-standard data types, Core Data provides two types of attributes: Binary Data and Transformable. Of greater interest is the second type, since it avoids the need to manually serialize objects in NSData. In the data model from the
project , the coordinates attribute is highlighted in the CDPlace entity, it is intended to store the coordinates as an instance of
Coords2D . Coords2D is an easy class for working with coordinates that supports NSCoding. Pay attention to its type - Transformable, thanks to this configuration it is possible, for example, the following:
CDPlace* cdPlace = … Coords2D* coords2D = ... cdPlace.coordinates = coords2D;
The problem appears when using Transformable attributes with mogenerator - how to specify a class so that property is generated correctly?
@interface _CDPlace : NSManagedObject {} ... @property (nonatomic, strong) Coords2D* coordinates;
The solution is the following: you need to add the attributeValueClassName =>% class_name% pair to the UserInfo attribute:
1. In Xcode, select the coordinates attribute,

2. On the right, select the Data Model Inspector tab,
3. In the User Info group, click + below the list and add:

With the next generation, property coordinates will be of type Coords2D.
Rename Entity
If you rename an entity, mogenerator simply generates a new pair of classes, deleting unnecessary and renaming the necessary files must be done manually.
Using the --orphaned and --model parameters together allows you to get a list of source files for which no matching entities were found in the model. For example, you can redirect mogenerator output to xargs + git to delete files for deleted and renamed entities in one command:
$ mogenerator --model ../Model.xcdatamodel --orphaned | xargs git rm
What else?
mogenerator supports custom templates, i.e. There is an opportunity to change the way you fill files as you like, unify your boilerplate code, create your template and use it with mogenerator.
The standard template provides the following set of buns:
- Validation - It is convenient to override attribute validation methods.
- % attribute% Value - for numeric and bool types there are convenient setters that allow you to avoid messing with NSNumber, for example:
NSInteger sum = entity.int32AtributeValue + 5;
- Convenient methods for working with MOC :
Entity* entity = [Entity insertInManagedObjectContext:context];
- Method for fetching all instances of an entity in the repository:
NSArray* allEntities = [Entity fetchAllEntities:context];
This is not a complete set; a standard template for generating classes is developed along with mogenerator.
Total we have a great tool to ignore which in my opinion today is no longer possible.