Rapture in Venice

:: Mobile Design and Development Shop specializing in iPhone, iPad, and Android

Getting Started with Mogenerator

NOW UPDATED FOR XCODE 5

If you’re an iOS developer using Core Data in your app, whether a n00b or expert, you should be using Mogenerator. I mean, really, you *should* be using it. If you don’t, well don’t worry, I’m not only going to tell you why you need it, I’m including a tutorial on how to use it!

So let’s get to it!

I know Core Data already, so why do I need Mogen?

Core Data is a huge beast of a thing. There’s so much to know, and you’re not going to get any new functionality from Mogen either. What you *will* get, however, is a Core Data that will be far, far easier to use. This is what Mogen does for you:

  1. Faster and easier generation of concrete classes for your model.
  2. A proper two-class treatment in that generation.
  3. Alleviates the need to wrap numeric attributes in NSNumber objects.
  4. Handy setter methods for manipulating sets easily.
  5. Handy wrapper methods for insertion/entity identification.

I can’t wait to get into it all, but first you need to install Mogen and set up your project!

Installation

The first thing you’ll need to do is install Mogen. It’s simple, you install Mogen from a DMG. After this one-time step, we’ll now configure your project to use it:

  1. In your project, open your project properties and tap the “+” button at the bottom of the Targets list.


  2. Add an “Aggregate” target (you’ll find it in the iOS/Other grouping). Tap Next.
  3. Name the target whatever you’d like. I’ll call mine Mogenerator. Hit Done.

  4. Now select the new target you just created, select the “Build Phases” tab, tap “+” to add a build phase then select “New Run Script Build Phase”.
  5. Open the Run Script group that just appeared, keep the Shell at /bin/sh, and then enter the following script if you’re using Objective-C:
     
    mogenerator -m MyCoreDataApp/MyModel.xcdatamodeld -O MyCoreDataApp/Model --template-var arc=true
     
    And for Swift:
     
    mogenerator -m MyCoreDataApp/MyModel.xcdatamodeld -O MyCoreDataApp/Model --swift --template-var arc=true
     
    You’re passing in your Core Data model path and directory you want the generated files to live (the directory will be created if it doesn’t exist), so feel free to change the names to match your project. Remove the ARC option if, for some reason, you’re not using ARC. Do note that we take advantage of mogen’s ability to automatically find your current model version. If you don’t have versions, or your project is brand new, this may fail. In that case, you’ll need to be more explicit with the model name. This would work:
     
    mogenerator -m MyCoreDataApp/MyModel.xcdatamodeld/MyModel.xcdatamodel -O MyCoreDataApp/Model --template-var arc=true
     
    And for Swift:
     
    mogenerator -m MyCoreDataApp/MyModel.xcdatamodeld/MyModel.xcdatamodel -O MyCoreDataApp/Model --swift --template-var arc=true
     
  6. When you create entities in your data model, be sure to populate the “Class” field with the same name as the entity. (You can name it whatever you want, actually, but that would be mighty stupid to do.)



Now, we’re all ready to go, but what did we win? I’ll outline that next.

Faster, Improved Class Generation

I’ve been programming iPhone apps for almost 3 years now and, I’ll be honest, I still can’t tell you the exact steps to generate Core Data classes. It seems to involve selecting the right entities in the model, adding a new file, and changing some check- — look, I don’t know. I think they made it a little easier recently, but it was crazy and I use Mogen now so I don’t care anymore. ;-) All I know is it’s much easier now.

Change your build target to “Mogenerator” (or whatever you called it) and hit ⌘B to build. And you’re done. At this point, since you generated new files, you’ll need to add them to your project. You won’t have to do this on future regenerations, but for new entities, yes.

You’ll notice that there are two sets of files, _Event.* and Event.*. If you’re not familiar with this pattern, it’s amazing. It’s also been used for years and shame on Apple that they don’t do this out of the box. The _Event.* files are generated and you should never touch them. The Event.* files are generated only if they don’t exist and you can feel free to add any methods and properties you like.

Yes, that’s right, gone are the days where you avoided adding methods to your concrete classes knowing that once you did you wouldn’t be able to generate them anymore. Add all you want, now! The clean coding gods will thank you!

From here on out, whenever you change your model, regenerate the classes, rinse and repeat.

Better Setters

Maybe I’m alone, but early on one of the mistakes I made over and over again was to forget that my numeric entity attributes were wrapped in NSNumber. I’d constantly write code like this:

if (user.isAdmin) {
    ...
}

WRONG! The isAdmin attribute is an NSNumber, so this will evaluate to true for all cases where isAdmin isn’t nil! I ran into this so many times I even contemplated scrapping Core Data to erase the emotional pain.

Not anymore with Mogen. You can now write the code as:

if (user.isAdminValue) {
    ...
}

This simple upgrade is a godsend! Setting attributes is equally easy, and you get to keep the original setters and getters to boot. You can use whatever is useful at the moment. With some attributes, I’ll use both versions:

Thank you, thank you Mogen!

Even More Useful Methods

Aside from the setters and getters, you get some useful methods for relationships, too. Now, I believe Apple has learned their lesson and now provide similar methods like these, but too little, too late. So, let’s say for example you have a entities named User and Role with a to-many relationship on User named roles. You can write code like this to add a role to the user:

User *user = [User insertInManagedObjectContext:moc];
user.name = @"John Blanco";

Role *role = [Role insertInManagedObjectContext:moc];
role.type = @"Administrator";

[user addRolesObject:role];

And you’re done. No need to create a mutable set or anything, it’s all handled for you. There’s a handful of other methods like this, one that lets you remove an object and two more that let you add or remove multiples objects in a set.

Validations, Too!

Mind you, this isn’t a Mogen thing. This is a Core Data thing. Validations let you test your data before saving to your persistant store. But, you might not even have known this existed! This is because you have to specify your validations in the concreate class and, if you’re not using Mogen, you’d have to keep rewriting them every time you regenerated your classes. WHAT?!

Now, you can specify validations like this:

- (BOOL)validateEmail:(id *)value error:(NSError **)error {
    if (self.email && ![self.email isValidEmailAddress] && error) {
        *error = [NSError errorWithDomain:@"MyErrorDomain" code:1];
        return NO;
    }

    return YES;
}

This is how you validate individual attributes, but there are other hooks available. Find out more about Core Data Validations to harness even more power.

Conclusion

I hope I’ve made my case for Mogenerator. It’s an invaluable tool! It simplifies anything and since I learned about it I haven’t worked on a project without it. Even better, since it’s a tool and not a library, it interoperates perfectly with other Core Data libraries like InnerBand’s Core Data Store and Magical Record.

Now go forth, young soldier!

  • Print
  • Facebook
  • Twitter

John Blanco

John Blanco is a freelance iOS and Android developer in Denver, CO. He's been developing mobile apps for 9 years, starting during the medieval days of Java ME, making him the ultimate hipster mobile engineer. Follow him on Twitter!

, ,

Comments are currently closed.

7 Responses to “Getting Started with Mogenerator”