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.rbThis 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.
IBThe second library is ‘IB’, which adds the
ib:openRake 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-RACExtensionsA 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:
motion create reactivekittens
- File → New → File…
- iOS User Interface → Storyboard, name it, create it
- Make it the initial VC
- Set the Class to you custom VC class name
- Give it a Storyboard ID
UIImageViewto the cell
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!