RACSignal for NSArray objects

I have an NSArray of ViewModel objects on my ViewController:

@property (non-atomic, strong) NSArray * viewModels;

The ViewModel looks something like this:

@interface ViewModel : NSObject

@property (nonatomic) BOOL isSelected;

@end

I am trying to create a RACSignal for enabledSignal in the init method of RACCommand:

- (id)initWithEnabled:(RACSignal *)enabledSignal signalBlock:(RACSignal * (^)(id input))signalBlock

This signal indicates that the command will be enabled if either 0 viewModel objects are selected, or if the number of selected view models is equal to the total number of ViewModels.

I can create a RACSequence that 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 can I create the right signal?

+4
source share
1 answer

( ) , KVO , .

. "" viewModels, -switchToLatest , :

@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 `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];
+6

All Articles