We're hiring!

We're actively seeking developers and designers for our Detroit & Ann Arbor locations.

ReactiveCocoa, RubyMotion, and InterfaceBuilder Can All Be Friends

I’ve really been enjoying using ReactiveCocoa lately. I’m sure I’d have felt the same if I was using it with Objective-C, but using via RubyMotion has provided a much lower barrier to focusing on the core concepts of reactive programming. If for no other reason, I prefer the language-building tools of RubyMotion to their counterparts in pure Objective-C.

One example of that comes from my preference for the Presenter-first pattern for writing software user interfaces. It takes a little work to adapt it to the iOS ecosystem, and Ruby seems up to the challenge. To give an idea of how you could apply the ideas of MVP and Presenter-first to a RubyMotion iOS app using ReactiveCocoa, I’ve prepared a sample app that does just that. Go take a look!

What Is This?

It’s a simple app that shows a set of random kittens, generously donated by placekitten.com. For demonstration purposes, I’ve thrown almost all of the application into a single file, and I’ve provided no unit tests. Those would both elicit a stern gut punch if suggested during a real project, but it makes this example nice and compact!

The demo also shows how one might use Storyboards with a ReactiveCocoa+RubyMotion app. In a real app, I would prefer to tie access to UIViewController instances from the Storyboard into some sort of dependency injection apparatus. Since my first choice of DI libraries is still Objective-C only, I skipped that for my demo.

There are a few libraries of note that I do rely on in the demo:

rac_extensions.rb

This file is pulled from the helpful ReactiveCocoa wrapper in RACSignupDemo-RubyMotion, which makes some of the RAC methods take vanilla Ruby blocks instead of lambda arguments. It also provides a replacement for some of the macros from ReactiveCocoa. While not required, I find that it cleans up spare parentheses and stabby lambdas.

IB

The second library is ‘IB’, which adds the ib:open Rake task that wires up InterfaceBuilder outlets for you. In my opinion this is a must-have if you intend to work with RubyMotion and still use InterfaceBuilder.

AFNetworking-RACExtensions

A helpful wrapper for the well-known AFNetworking library. Makes short work of fetching cats from the internet!

How I Made It

Assuming typical iOS prerequisites and a license for RubyMotion, here’s how I started:

  1. motion create reactivekittens
  2. customize Rakefile, Gemfile
  3. bundle install
  4. copy rac_extensions.rb to app/
  5. rake ib:open
  6. File → New → File…
    • iOS User Interface → Storyboard, name it, create it
  7. Drop a Collection View Controller onto the storyboard
    • Make it the initial VC
    • Set the Class to you custom VC class name
    • Give it a Storyboard ID
  8. Set the Class on the cell to your custom cell class
  9. Add a UIImageView to the cell
  10. Add an image outlet declaration to your cell class (shown below)
  11. Right-click-drag from the Cell to the UIImageView, and select the name of the outlet you just created.

There’s a lot more to do to completely recreate the demo app, but you should be able to pick up the rest from the repo. When you wire up outlets in IB, you can access them from your Ruby classes, thanks to IB:

outlet :image, UIImageView

And just look at the way we can wire up model and view streams in the presenter:

view.kittens = model.kittens

There are a few more interesting examples of using ReactiveCocoa in the code, so go check it out!

Karlin Fox (41 Posts)

This entry was posted in Ruby Motion and tagged , , , . Bookmark the permalink. Both comments and trackbacks are currently closed.