Practical Software Architecture, Swift Style
The main software architecture pattern in iOS is model-view-controller
(MVC),
but when projects hit a certain level of complexity the fact that large
amounts of code end up living in the ViewController layer in iOS can start to
get ugly and hard to work with. This has lead to borrowing patterns from the
model-view-viewmodel
(MVVM)
pattern in many projects at work.
In Objective-C this meant making heavy use of data bindings between the view-
model and view layer, with
RZDataBinding helping to take a
lot of the rough edges off of data bindings. In most cases, this worked really
well, and things like coalescing updates took care of many of the edge cases
like notification storms or bad intermediate state being generated.
In Swift, there isn’t a clear win for data binding yet, so we’ve pulled back
on the “bind everything” side of MVVM. One pattern that I’ve found useful is
keeping view models as lightweight structs, having all of their internal
values immutable, and generating a new view-model and replacing it on the
view, which updates on didSet
for view viewModel variable.
Overall, it’s leading to more thinner layers in an app, because it means the
viewModel doesn’t contain any intelligence about self updating, which moves
the self updating logic into the viewController, or into a services layer
object that that produces a model object, which then can be parsed into the
appropriate view-model.