Hi there,
Chapter 20 of the RxSwift book advocates the use of Action
, as something really useful and “Perfectly suited for MVVM” (the title of a section, not my words). But after toying a bit with them I’m about to drop its use and I would like to know if there’s something I may be missing.
From my point of view:
Action
excels at taking charge of a button state, so it automatically disables the button while the associated action is in progress. But the only way to do this is to link the button to a CocoaAction
(Action<Void, Void>
). This means that the action has no input parameters, so it has to take its input values from elsewhere. This in turn means introducing state into the view model, as you are no longer combining observable streams to produce some output; you are taking some value from elsewhere to create a completable piece of work. Of course you may use a BehaviorSubject
or a connectable observable to keep state in a reactive world, but I’ve found that this pollutes the view model and complicates programming it.
If we instead use an action with input parameters we transfer the responsibility for feeding those parameters to the view controller and we must combine some observables in the view controller from input fields (or even state exposed by the view model) to provide the input to the action, breaking the view controller <-> view model boundaries and responsibilities: You are no longer binding the view to the view model, but you are only binding certain combinations of behaviors to actions in the view model. In addition when you do this you lose the button related functionality, so Action
becomes a glorified closure with some reactive related behavior.
Summing up, I’ve found that adding Action
s to my application:
- Introduces imperative programming concepts into reactive programming
- Forces you to maintain state for all but non trivial view models, complicating the view model and the reasoning about it, or
- Breaks the view controller <-> view model responsibility boundaries
What am I missing?
For the record, my non trivial view model is a video player view model, where you have several buttons to control playback, and the behavior of some of the buttons depend on the current state of the playback (for example, think of the usual combined play/pause button, where the button fullfils both functionalities, changing its icon depending on whether the video is currently playing or paused)
Thanks, best regards
José