I have an NSArray of ViewModel objects on my ViewController:
@property (nonatomic, strong) NSArray *viewModels;
A ViewModel object looks something like this:
@interface ViewModel : NSObject
@property (nonatomic) BOOL isSelected;
@end
I am trying to create a RACSignal for the enabledSignal on a RACCommand's init method:
- (id)initWithEnabled:(RACSignal *)enabledSignal signalBlock:(RACSignal * (^)(id input))signalBlock
This signal will tell the Command to be enabled if there are either 0 viewModel objects selected or if the number of viewModels selected is equal to the total count of the viewModels.
I can create a RACSequence which will give me the viewModel objects that are selected by this code:
RACSequence *selectedViewModels = [[self.viewModels.rac_sequence
filter:^BOOL(ViewModel *viewModel) {
return viewModel.isSelected == YES;
}]
map:^id(ViewModel *viewModel) {
return viewModel;
}];
How would I go about creating the valid signal?
To observe all of the latest view models (and only the latest view models) for changes, we'll need to set up new KVO observations each time the array changes.
The most natural way to represent this is with a signal of signals. Each "inner" signal represents a set of observations on one version of viewModels
, and then we'll use -switchToLatest
to ensure that only the newest signal takes effect:
@weakify(self);
RACSignal *enabled = [[RACObserve(self, viewModels)
// Map _each_ array of view models to a signal determining whether the command
// should be enabled.
map:^(NSArray *viewModels) {
RACSequence *selectionSignals = [[viewModels.rac_sequence
map:^(ViewModel *viewModel) {
// RACObserve() implicitly retains `self`, so we need to avoid
// a retain cycle.
@strongify(self);
// Observe each view model's `isSelected` property for changes.
return RACObserve(viewModel, isSelected);
}]
// Ensure we always have one YES for the -and below.
startWith:[RACSignal return:@YES]];
// Sends YES whenever all of the view models are selected, NO otherwise.
return [[RACSignal
combineLatest:selectionSignals]
and];
}]
// Then, ensure that we only subscribe to the _latest_ signal returned from
// the block above (i.e., the observations from the latest `viewModels`).
switchToLatest];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With