Dev Blog

I’ve been in a very passionate relationship with RVM, as have many others (it gets around, see) and I’ve seen a growing interest in a more attractive, “modest is hottest” alternative called rbenv. I thought they were fools at first, RVM has been nothing but pure joy for me. Until…

See, RVM fit two awesome needs: gemsets and managed ruby versions. Gemsets allowed me to stay away from the dreaded bundle exec preceeding my every command, as well as “blah blah gem version blah has already been activated!” errors. But gemsets also cause you to re-download every gem for every project, which began to wear on me. It was slow, and eating into my GB’s. But, it turns out the the bundle exec thing has been solved and with that, it’s a no brainer. I dumped RVM and rbenv is my new best friend. Fair-weather friend, indeed. Much lighter-weight and they tell me it’s safer for some reason, which I blindly accept.

I view this also from a teaching perspective. I run a Ruby on Rails student group at the University of Utah and teaching RVM, and in particular gemsets, is a friggin’ nightmare for beginners. rbenv + rbenv-bundler is a much cleaner option that is less likely to catch up beginners and experts alike. Set it and forget it! (I love that this video is a youtube video of a youtube video.)

As an aside, I found this really cool gist that installs a souped-up version of Ruby that runs about 30% faster. Again, that time adds up with how slow Rails is these days. I found my speed-up to be consistent with that gist. A win-win.

We’re working on a new app, as some of you may know, and it’s required we find some sort of database to get food data from. Calories, protein, serving sizes, etc. We started with the USDA food database. This thing is a piece of garbage. Naming conventions are inconsistent and absurdly long, sometimes in ALL CAPS even. It was also missing several fairly common foods (coconut oil, anyone?). Not to mention it’s distributed as either a Microsoft Access database, an Excel sheet, or a custom file format. Really? Access or Excel? Those were immediately unusable to us, so we were left with the custom file format. This thing is a real piece of work, let me give you a taste:

I spent a good many hours writing a custom parser for that beauty. Why in the world can’t they just do JSON, or I’d even get my big-boy pants on and suffer through some XML. We no longer live in an age when your best option is custom file formats! At the VERY least provide some sort of parser I can use. I… just… how…

So we decided to pivot. We did some searching and found FatSecret. It’s paid for the Premier tier (which we’ll probably end up having to get) but it also has a free plan. Hallelujah.

After determining that it was our best option, I unknowingly dove into the pits of OAuth hell. It authenticates with OAuth, which is fine, except there’s not fantastic iOS library support for OAuth. I did some searching and the best I could find was OAuthCore, which generates a signed header, but I needed it as a query string in a GET request. Wasn’t too tough, just switched a few lines of code, debugged it a good while, scratched my head, and suddenly it worked. I was moments away from giving up when light shown through the heavens and I was Enlightened. I got back some JSON of food. And it was very desirable. Consistent naming, hundreds of results, it was beautiful. I cried. Not really, I drank some Pomegranate 7-up and kissed my wife.

All there was left to do was abstract my code into an open source library. I’d give you a song-and-dance about MT’s commitment (read: burning passion) for open source (which is true) but it really, in this case, came down to how cool CocoaPods is that there’s really no reason not to open source something like this. Here it is, if you ever need it. I pray even my worst enemy won’t find that USDA database.

Adam claimed the other day that in every situation he could think of, blocks could replace protocol delegation in Objective-C. I had never thought about this and almost dismissed it as soon as I heard it, but I’ve thought about it a lot the past few days. I wrote an experimental, drop-in replacement for UITableView called MTBlockTableView that demonstrates this idea. There’s 3 particular situtations where I use delegates the most, and I’d like to expand on each of them and the pros and cons of block versus protocol delegation.

UITableView

In MTBlockTableView, we took the typical delegate implementation and used blocks for each delegate method. Consider the difference from the snippets below:

Behind-the-scenes, MTBlockTableView is its own delegate and data source and it simply calls the corresponding blocks for each of the delegate methods.

However, in this particular example where the view controller is the delegate of only a single UITableView, you kind of break even, if you ask me. They’re both pretty much the same in terms of lines of code, and it mostly comes down to taste. With blocks, there’s no conforming to protocols which can be nice, but you also don’t get the compiler-enforced @required/@optional protocol method niceties. But let’s take another example.

UIAlertView

Better uses for blocks can be found when you have multiple objects of the same type using the same object as their delegate. UIAlertView comes to mind, where just one works fine:

But what if you have two alert views? You could create distinct objects, each to be separate delegates (WAY too much work for something as simple as UIAlertView ought to be), or you could rig up something like this:

Now each UIAlertView is in charge of calling its own, specific finished code, as it should be. Again, behind-the-scenes it’s just conforming to its own protocol and each delegate method is calling its corresponding block. This is an out-right win as far as I’m concerned. UIAlertViews are meant to be quick-and-easy, but that moment when you realize you have to conform to a protocol to respond to user action is always a brutal one, and having multiple alert views gives me hives. Fewer lines of code and ideas are grouped together logically.

I recently tried using RKClient, an HTTP request client, from the RestKit framework for an open source project and ran into this same problem. You tell the client to fetch JSON at some URL and it calls a delegate method when it’s done. What if you’re making multiple requests, and you want to handle the JSON differently for each request? You’re hosed. Delegates and protocols break down in this situation. I ended up using SVHTTPRequest instead, which uses blocks instead of delegates, and it’s really quite elegant.

(To be fair, I was using RKClient in an unorthodox way, I wasn’t using the object mapping that’s meant to be used with RestKit, which would have solved this particular problem, but you get the idea.)

This can also apply to our previous example where you might want one view controller to control two trivial table views. Rare, perhaps, but still a flexibility bonus that a block-based approach has over protocols.

One more example.

Modal View Controllers

Displaying modal view controllers usually goes something like this for me, where MySourceViewController presents MyDestinationViewController:

Which is all fine and well, but in this situation you are still looking to do something quite simple. That’s a fair bit of code (declaring the protocol, conforming to it, etc) and blocks provide something a little more succinct:

Again, a huge win. No need to define a protocol, or conform to it. You handle both the presenting and the dismissal all at once. It’s much more elegant, natural, and pleasurable to code this way (once you get over the ugly block syntax), having written code using this convention for about a week now.

Adam and I feel this is the next natural progression of the delegate design pattern. Protocols were created because smart guys with beards realized that in certain circumstances, objects didn’t need to know what type another object was, just that it implemented certain methods. This was (and still is to an extent) very expressive, and is a key feature of why UIKit trumps many other graphical frameworks. But even that is overkill sometimes. In the last two situations I discussed above, the object doesn’t even need to know about the object at all, just that it can call a method.

We’re not saying do away with delegates altogether since in certain situations, like with UITableView, blocks are not an all-out win (though what if you wanted one view controller to control two table views?). But we are saying some of the UIKit framework, such as UIAlertView, would be much more elegant and expressive if we could use blocks in place of delegates. What do you think? Let us know at @mystrou on Twitter.