mogenerator v1.1

Or mind the (generation) gap again…

Now that I’ve had time to unwrap Christmas presents, I’ve also had time to explore some of the new things in mogenerator v1.1. Along with a number of bug fixes, it has support for ObjC++ (.mm) files and a number of other goodies. I’d previously written about getting started with the earlier version — this post brings that information up to date.

Installing mogenerator

In addition to the latest version of mogenerator, there is also a test application — mogeneratorTestMule — which provides a convenient way of testing mogenerator. Here’s how to get started:

1Checkout MiscMerge and mogenerator from https://svn.sourceforge.net/svnroot/redshed/. If you also want to build and run the mogeneratorTestMule project, checkout the CoreData+JRExtensions as well.

2For ease I put the three folders in a mogenerator_1_1 folder to keep project path relationships happy.

3Make a folder called mogenerator in ~/Library/Application Support/ and move the four *.motemplate files into there. If you already had the template files from the previous version don’t forget to do this step otherwise you’ll end up generating files using the older templates.

4Open mogenerator.xcodeproj. If you’re asked for the project root, select the folder enclosing the mogenerator folder.

5Click ‘Build’. The mogenerator executable will be built in build/Release/, or wherever you have Xcode set up to build.

6Move the mogenerator executable to a more convenient location, such as /usr/local/bin. This version generates its files in the current directory when invoked, so the previous requirement of having it alongside the .xcdatamodel is no longer necessary.

Testing it out

As before, check it is working and is the correct version:

david$ ./mogenerator -version
mogenerator 1.1. By Jonathan 'Wolf' Rentzsch.

The help is as it was before:

david$ ./mogenerator -help
mogenerator [-model /path/to/file.xcdatamodel] [-baseClass MyBaseClassMO] [-includem include.m] [-version] [-help]
Implements generation gap codegen pattern for Core Data. Inspired by eogenerator.
		

Creating files

The TestMule project provides a convenient way of testing out the command. The _xMO.h and _xMO.m files are automatically generated by mogenerator. The xMO.h and xMO.m files are generated initially if they don’t already exist. Once they’re created, mogenerator will leave them alone, ensuring that your custom logic is not overridden.

For an example of custom logic, have a look at HumanMO.m:

- (NSColor*)hairColor {
	return [NSUnarchiver unarchiveObjectWithData:[self hairColorStorage]];
}

- (void)setHairColor:(NSColor*)value_ {
	[self setHairColorStorage:[NSArchiver archivedDataWithRootObject:value_]];
}
		

To use mogenerator, first cd to the directory where you want the files to be generated:

cd ~/mogenerator_1.1/mogenerator/mogeneratorTestMule/MOs/
		

To create the MO files:

mogenerator -model ../mogeneratorTestMule_DataModel.xcdatamodel
		

At this point, warning messages will appear:

../mogeneratorTestMule_DataModel.xcdatamodel:Human.meaninglessRelationship: warning: Human.meaninglessRelationship -- relationship doesn't have an inverse
		

This warning is correct — the meaninglessRelationship doesn’t have an inverse relationship — but relates to issues within the model itself, rather than a problem with mogenerator.

To create the files and also an include.m file, so that all of the computer and human files can be included from one file:

mogenerator -model ../mogeneratorTestMule_DataModel.xcdatamodel -includem include.m
		

To create the MO files, and also specify that a pre-existing base class should be used:

mogenerator -model ../mogeneratorTestMule_DataModel.xcdatamodel -includem include.m -baseClass MyBaseClass
		

This ensures that classes which would otherwise have been subclasses of NSManagedObject are instead subclasses of the specified base class instead. In the case of the TestMule example this includes the Human entity: it has a class of HumanMO, but no parent entity. The MyBaseClass.h and .m files show how the base class can add additional functionality in this way.

Re-running mogenerator after changes to the data model

While mogenerator is impressive enough at creating these initial files, the beauty of mogenerator is that it is more than just a quick way of generating boilerplate code — it is a way of keeping the computer files up to date as the data model changes. Re-running the command from the terminal is one way of doing this, but tighter integration with Xcode would be nice.

Scott Guelich has a nice AppleScript solution which adds a menu item to Xcode to run mogenerator. This provides a really easy way of invoking mogenerator, although without the ability to customize the parameters passed to it.

Another way of re-running mogenerator is supplied in the TestMule project — a mogenerate.command file, which uses a location-aware .command file to get the job done:

#!/bin/sh
cd "`dirname \"$0\"`"
cd MOs
mogenerator -model ../mogeneratorTestMule_DataModel.xcdatamodel -baseClass MyBaseClass -includem include.m
		

One benefit of this approach is that it provides a good way of specifying the destination directory, the base class and the include file options within the project. Double-clicking the file from the Finder will run the command. If a trip to the Finder is too much effort, adding mogenerate.command to the project file list — remembering not to add it to an actual target — will allow it to be double-clicked from within Xcode. Running the .command file will cause the sudden creation of a terminal window in which to display the output of the command, so it isn’t totally seamless.

Coming soon…

It looks like there are more good things coming for mogenerator — Jonathan has hinted at fetch request wrappers, tighter Xcode integration, a binary installer, and even more magic!

Post your own comment here:











Note: be friendly! We reserve the right to moderate inappropriate, offensive, or wildly off-topic comments. Your email address is required, but won't be displayed. All comments are moderated, so don’t expect them to show up instantly.