markvasiv
markvasiv

Reputation: 522

Observe object change in NSArray using ReactiveCocoa

I'm creating simple contact application trying to learn ReactiveCocoa and MVVM. I store array of cell's ViewModels in my tableView's ViewModel. When user enters into tableView's editing mode, some properties of some cell's ViewModel can be changed as user changes cell text. I want to observe these changes in order to enable/disable Done button and accordingly enable/disable signal for saving the data to the model. How can I observe these changes in the tableViews view model?

Here is a snippet of code I tried to use:

-(RACSignal *)executeCheckChange {
    return [RACObserve(self, cellViewModels)
            map:^id(NSArray *viewModels) {
                for (id viewModel in viewModels) {
                    if([viewModel isKindOfClass:[STContactDetailsPhoneCellViewModel class]])
                    {
                        STContactDetailsPhoneCellViewModel *phoneViewModel = (STContactDetailsPhoneCellViewModel *)viewModel;
                        if([phoneViewModel isChanged])
                            return @(YES);
                    }
                }
                return @(NO);
            }];
}

But this RACObserve is only invoked if the array itself is changed, but not the element of array.

Upvotes: 3

Views: 1226

Answers (2)

Abhishek Bhardwaj
Abhishek Bhardwaj

Reputation: 98

To observe the changes to the properties of a class you need to add observer to that property using the key value observing functionality.

Upvotes: 0

markvasiv
markvasiv

Reputation: 522

In my particular case I was able to solve the problem this way:

-(RACSignal *)executeChangeCheck {

    @weakify(self);
    return [[RACObserve(self, cellViewModels)
             map:^(NSArray *viewModels) {

                 RACSequence *selectionSignals = [[viewModels.rac_sequence
                 filter:^BOOL(id value) {
                     return [value isKindOfClass:[STContactDetailsPhoneCellViewModel class]];
                 }]
                 map:^(STContactDetailsPhoneCellViewModel *viewModel) {
                     @strongify(self);
                     return [RACObserve(viewModel, editPhone)
                             map:^id(NSString *editPhone) {
                                 return @(![editPhone isEqualToString:viewModel.phone]);
                             }];
                 }];

                 return [[RACSignal
                          combineLatest:selectionSignals]
                         or];
   }]
  switchToLatest];


}

All in all, every time my array changes, I create set of observations on each of ViewModels, filter them in such a way that I observe only these that I'm interested, compare values from observations to the original value and ensure that only newest signal takes effect.

Upvotes: 3

Related Questions