For the past few months I’ve gotten the opportunity to develop in Ruby and experience first-hand the awesomeness that is Ruby on Rails. I’ve been keeping up with my normal iOS development and would be lying if I said RoR development hasn’t changed my Objective-C habits. Ruby/Rails development has drilled into my head ideas such as DRY (Don’t Repeat Yourself), CoC (Convention over Configuration), and the idea of meta programming. I’ve started to realize that Objective-C and the iOS SDK leads you into the direction of hard-coded repetition: I cringe every time I implement UITableViewDataSource methods ::I’m looking at you UITableViewCell:: and I’m tired of implementing the same logic in navigation-based apps.
Objective-C has some built in support for meta-programming with calls such as
makeObjectsPerformSelector:. I’ve recently come across some nice solutions for UITableViewDataSource methods in iOS Recipes: Tips and Tricks for Awesome iPhone and iPad Apps by Paul Warren and Matt Drance.
I decided I’d see how far I can push the idea of meta-programming in Objective-C and came up with a fun solution for the very common navigation pattern: List of Models View -> Details of Model View. The solution relies heavily on CoC and meta programming.
The solution makes use of a custom class,
ModelListViewController, which implements three methods:
The implementation of each method is fairly short:
The method that makes magic happen,
modelNameForList, looks at the class name and pulls out anything before “ListViewController”. This allows you to dynamically insert new Model objects (assuming Core Data usage – but would work for anything) or dynamically initialize and present detail view controllers. The
presentViewControllerForObject:newObject: method expects detail view controllers to be named something like ModelViewController, where “Model” is replaced with the actual model name – Convention over Configuration FTW!
Using an example: Let’s imagine you have a model named Car and have added a subclass of
CarListViewController, and a class called
CarViewController. By simply subclassing
ModelListViewController, you’ve already achieved normal navigation based behavior for adding a new Car or tapping to view details of an existing Car with 0 lines of code in any of the Car classes. Of course, this example assumes you’ve implemented some of UITableViewDelegate and DataSource methods in ModelListViewController, but those examples are for another post.