With the release of Ash Furrow’s new book on Functional Reactive Programming
in iOS, I’ve seen a lot of debate about whether or not this whole
paradigm shift is a good idea. Why do it? Isn’t what Apple provides with their
specific flavor of Model-View-Controller sufficient? What the heck
is Model-View-ViewModel?
OMG! The acronyms! It burns us!1
That’s what leads me to this post. I would like to build a bridge that
stretches across the divide between the traditional way to build iOS
applications and the strange new world with MVVM, Reactive
Cocoa, RXCollections and the like.
You Are Not Stupid
First off, you are not stupid if you have trouble groking the README and
documentation of Reactive Cocoa. It’s a very different paradigm than what grew
up around Objective-C. It’s a clever abuse of the C preprocessor—a layer on
top of Objective-C, which itself is a layer on top of C, etc.
All this extra syntax makes it hard to just jump in and read the code. It helps
to know how and why the syntaxes grow into what they are today. After all,
we’re quite forgiving when it comes to the block syntax Apple gave to us,
right? Right?!?!
The hacked and layered nature of things like Reactive Cocoa have downsides, for
sure. But I’m excited to see experiments giving us new primitives with which to
compose our application logic. And it’s not just academic. Github is
behind Reactive Cocoa and applies it to real world problems in their Mac and
iOS applications.
You’re Already Closer To View-Models Than You Think
So, back to view-models.
Think about what a table view data source does in your application.
It’s not your “model” layer in a classic MVC sense. Your models might be, say,
NSManagedObjects
as part of a Core Data store. These models have validation
rules, transformed properties, and relationships that construct what the core
of the application does.
A table view data source is none of these things. It’s purely a layer between
the table view and the model. The model defines lists of things, but the table
view data source transform those lists into sections and rows. It also returns
the actual table view cells, but that’s not what I’m focusing on here. The key
is its role as a middle-tier data transformer.
By default, because of Apple’s templates and documentation, we typically use
table view controllers as the data source. There’s nothing wrong with that in
itself, but it can lead to very large view controllers that both manage
representations of screen state (navigation, transitions, and so forth) and
feed data to the table views.
I’ve found great success creating separate NSObjects
that implement the
UITableViewDataSource
protocol and dedicating those as data sources of table
views. We end up with more focused objects, they’re simpler to test, and it
leads us this realization…
We’ve just made a bunch of view-models!
Yes, the people who work with MVVM all the time will rightly criticize that
statement. I’m overgeneralizing a bit, but bear with me. My point is that the
table view data source is a “model” layer between the actual list of data and
the table view that displays it.
I bring this up to show that the core of MVVM isn’t as foreign a concept on iOS
as it seems. If you read Ash’s book, you’ll get a heavy dose of all
the other things that MVVM brings with it, but you can at least get a head
start in your understanding by thinking of the way the data source sits as a
transforming layer between your model and your view.
Why Stop There?
Imagine this same mechanism generalized to other areas. Instead of bogging down
your NSManagedObject
subclasses with extra methods to display data in
different formats, you build intermediate view-model objects that your views
could consume and watch. If you update a primitive integer on your model, the
view-model sees that change and updates the formatted NSString
representation. And the view sees that change and updates the text label on
the screen.
Next, imagine you had some sort of syntax to describe the bindings between the
model, the view-model, and the view. If you’re still tracking with me then
you’re ready to take a look at things like Reactive Cocoa. It’s a syntax built
on top of Objective-C through which you bind subscribers to producers of
events. It’s like KVO but with broader implications.
I hope this helps a bit if you’ve been curious about the Reactive Cocoa craze
on iOS. I don’t think it’s above critique, but don’t write it off just because
it isn’t the traditional way. We need more experiments like this that help us
describe problems with primitive structures.
Count me in.
✦ Permalink