MOGenerator integration in XCode

MOGenerator is a command line utility that generates NSManagedObject class files based on you model files. It creates a NSManagedObject derived class for each entity of your model.
The utility can be run manually every time you change your model files (.xcdatamodeld).
This manual process can easily be forgotten, and ideally we want it to automatic regenerate the files every time you change the model.
We can use XCode Build Rules to add an extra step on the processing of model files. So every time you change them XCode itself will run MOGenerator and generate new files.
To do this follow this steps:

  • Create a folder inside your project called MOGenerator and copy the mogenerator binary file inside. I normally place it inside a folder called Libraries/MOGenerator inside the project. If you are a GIT user you can setup it as a git submodule in your project .
  • Open the Project settings view, select your target, open the Build Rules tab.
  • Add two new build rules, one for “Data model files” and another for “Data model version files” this is done be selecting the Process dropdown.
  • Change the Using dropdown to Custom Script
  • Add the following code to the script text box.  (Here is a list of all XCode environment variables).
  • For Data model files:
mogenerator --model "${INPUT_FILE_PATH}" --output-dir "${PROJECT_DIR}/XXXXX/Source/Model" --template-var  arc=true
  • For Data model version Files:
mogenerator --model "${INPUT_FILE_PATH}" --output-dir "${PROJECT_DIR}/XXXXX/Source/Model" --template-var  arc=true
  • Change the output-dir parameter to your specific generation path. This is the path where mogenerator will save the files.
  • Set the Output Files to the following values:
  • Data model Files:
  • Data Model Version Files:
  • Next step is to enter the name of the Class for your entity. Entity name and Class have to be the same
  • Build the project and check if you don’t get any failures in the build process.
  • Any entities which are new (that is, which MOGenerator has not encountered in a previous build) will need to be manually added to your project. This step only needs to be performed when you have new entities, not during updates to existing entities.
  • If you have multiple targets in your project which utilize your data model, you’ll need to add these build steps for each target to make sure the model is kept up to date for each target. If this is the case you could consider to move the script commands to an external script file and refer to it on the shell script in XCode.

XCode Build and Version numbers based on GIT

Since XCode 4.3 you can find in the Summary Tab of your targets the following fields: Version and Build.

  • Version should be used to identify the “comercial” version of your app, something like 2.0, for more details on how to proper change version numbers have a look at
  • Build should be a internal number to unique identify versions of your app.

Normally Version numbers are changed manually every time you prepare a deploy of a new app but Build numbers should change automatically every time you do a new build.
One initial idea could be using the current GIT commit hash number to fill the Build number, but there is a issue here: Apple wants that this number always increases from version to version.
So to go around this I decided to use the number of commits existing on the git repository. This is a number that always goes up while you are developing.

But how to integrate this with XCode and better yet make it automated?

Just follow these instructions:

  • In your Xcode project, create a new Bundle target called UpgradeVersionNumber.
  • Select that target and add a new Run Script phase to the Build phases.
  • Insert the following script in Run Script phase, replacing the path to your git executable if need be:
    # grabbing version number from plist.
    COMERCIAL_VERSION=`/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" Info.plist`
    # grabbing number of commit in developer to create a version number
    BUILD_VERSION=`git rev-list HEAD | wc -l | tr -d ' ' | tr -d '\n'`
    # grabbing commit hash from git
    GIT_VERSION=`git show --abbrev-commit | grep '^commit' | sed 's/commit //' | tr -d '\n'`
    echo "#define GIT_VERSION $GIT_VERSION" > InfoPlist.h
    touch Info.plist
  • Make UpgradeVersionNumber a dependency of your main target.
  • Add the “InfoPlist.h” to your .gitignore file.
  • In your main target’s build settings:
  • Turn on Preprocess Info.plist File
  • Set Info.plist Preprocessor Prefix File to InfoPlist.h
  • In your main target select the summary tab and on the Version Number field write BUILD_VERSION
  • Now each time you build the main target, the version will be populated in the build’s Info.plist.
  • As an optional step you can also add a custom entry to the plist called GitVersion and set it with the value GIT_VERSION.
  • Now when the script runs you also gonna get the Git hash number for the build on the Info.plist.
  • You can then use the following code to display it inside the app
[NSBundle mainBundle] objectForInfoDictionaryKey:@"GitVersion"];