De-stringing entity descriptions

October 22nd, 2011
#core data

Application requirements evolve, which require us to refactor existing features. For the most part, Xcode's built-in refactoring tools work well; however, an area where the refactoring tools can't help is with stringy APIs. Core Data seems to be full of stringy method parameters - in this article I want to look at how we can de-stringify NSEntityDescription to allow for greater compile protection and super-charge Xcode's refactoring tools.

A photo showing coloured yarn

Changing people to players

If I have a Core Data entity called: Person and as my application evolves I decide that Person is no longer an accurate description for that entity, instead Player would be better. I'd fire up the rename refactoring tool and change the name with Xcode taking care of cascading the name change through the codebase.

However if my NSEntityDescription declarations looked like this:

[NSEntityDescription insertNewObjectForEntityForName:@"Person" 
                              inManagedObjectContext:self.managedObjectContext];

The refactoring tool wouldn't change "Person" to "Player". The project would compile, but when this statement is executed the app would crash. I could search for the word "Person" and change it to Player" however, this is very manual and risks the chance that I don't catch them all.

A better approach is to get the refactoring tool to do it for us:

[NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([Person class]) 
                              inManagedObjectContext:self.managedObjectContext];

Here we use NSStringFromClass([Person class]) to create the needed string, but we keep the connection with the actual class. Now the rename refactoring tool can spot that [Person class] should become [Player class] and make the necessary change.

By de-stringing the NSEntityDescription declaration, we no longer need to wait on discovering a crash at runtime to know if we changed all the uses of Person to Player. Instead, the refactoring tool can do a better job of getting rid of Person for us. And if any Person declarations make it past the refactoring tool, the compiler acts the ultimate safety net - as Person no longer exists, trying to use it will cause the project to fail to compile.

What do you think? Let me know by getting in touch on Twitter - @wibosco