I have a method on ParentViewModel which returns an RACSequence of ViewModel objects like so:
- (RACSequence *) viewModels
{
return [self.models.rac_sequence map:^id(Model *model) {
return [[ViewModel alloc] initWithModel: model];
}];
}
Each of the ViewModels has a state property on which is an enum and has 3 states: NotStarted, InProgress and Completed. When all the ViewModels in my sequence have the state Completed I know ParentViewModel is valid. I have a validSignal on the ParentViewModel which I want to derive the fact that is valid from the viewModels sequence. At the moment I have this code:
BOOL valid = [[self viewModels] all:^BOOL(ViewModel *vm) {
return vm.state == Completed;
}];
Which gives me an indicator if all ViewModels in the sequence are valid. How can I then turn this into a RACSignal which will update every time the state property on one of the ViewModels changes?
You need first to turn state
into a RACSignal
, and then everything is easy from that point.
The final code will be something like the following:
RACSignal *valid = [[RACSignal combineLatest:
[[self viewModels] map:^id(ViewModel *viewModel) {
return RACAbleWithStart(viewModel, state);
}]
]
map:^(RACTuple *states) {
return @([states.rac_sequence all:^BOOL(NSNumber *state) {
return state.unsignedIntegerValue == Completed;
}]);
}
];
The first block maps each of your view models into a signal that observes the state
property (with the starting value as first value of the signal).
combineLatest:
will take a collection of RACSignals
and will create a new signal that fires everytime one of the underlaying signals changes, and sends a RACTuple
with the value of each signal.
That RACTuple
is then converted into a RACSequence
, and we can generate a value of @YES
or @NO
depending if all the values are Completed
or not.
I think the result is the signal you were looking for.
(Disclaimer: I’m new to ReactiveCocoa, so there may be an easier way).