Search code examples
objective-creactive-cocoa

Collect signal values to an array using ReactiveCocoa


I use ReactiveCocoa to record the taps in an array:

@interface ViewController : UIViewController
@property (strong, nonatomic) NSArray *first10Taps;
@property (strong, nonatomic) UITapGestureRecognizer *tapGesture;
@end

@implementation ViewController
- (void) viewDidLoad
{
  [super viewDidLoad];

  RACSignal *tapSignal = [[self.tapGesture rac_gestureSignal] map:^id(UITapGestureRecognizer *sender) {
    return [NSValue valueWithCGPoint:[sender locationInView:sender.view]];
  }];

  // This signal will send the first 10 tapping positions and then send completed signal.
  RACSignal *first10TapSignal = [tapSignal take:10];

  // Need to turn this signal to a sequence with the first 10 taps.
  RAC(self, first10Taps) = [first10TapSignal ...];
}
@end

How to turn this signal to an array signal?

I need to update the array every time a new value is sent.


Solution

  • Thanks for Michał Ciuba's answer. Using -collect will only send the collection value when the upstream signal is completed.

    I found the way using -scanWithStart:reduce: to produce a signal which will send the collection every time a next value is sent.

    RAC(self, first10Taps) = [firstTapSetSignal scanWithStart:[NSMutableArray array]  reduce:^id(NSMutableArray *collectedValues, id next) {
      [collectedValues addObject:(next ?: NSNull.null)];
      return collectedValues;
    }];