Pooja Bansiya
Pooja Bansiya

Reputation: 83

ReactiveCocoa: sendNext to a subscriber in asynchronous programming

I am trying to use ReactiveCococa for network connection using NSInputStream & NSOutputStream . The connect code looks as follows:

-(RACSignal*) connect: (NSString *) url {

   return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber>  theSubscriber) {
          self.subscriber = theSubscriber;

           // create inputStream and outputStream, initialize and open them

          [self.inputStream open]
           [self.outputStream open];
    }];
    return nil;
 }

-(void) stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode {

switch (eventCode) {
   case NSStreamEventHasBytesAvailable:
        //read from input stream
         NSArray * data = read_InputStream;
         [subscriber sendNext:data];

        break;
   }
   ...
 }

I have to store the value of subscriber and call sendNext on it, when I receive data in the callback method.

Is there a better way to handle this in ReactiveCocoa and avoid declaring subscriber property. Besides, this will not work with multiple subscribers.

Upvotes: 1

Views: 630

Answers (1)

Erik J
Erik J

Reputation: 402

You can use rac_signalForSelector to turn a delegate callback method into a signal. Then you can subscribe to this signal inside createSignal's didSubscribe block. Something like this:

- (RACSignal*)connect:(NSString *)url
{
    return [RACSignal createSignal:^RACDisposable*(id<RACSubscriber> theSubscriber)
    {
        // create inputStream and outputStream, initialize and open them

        [self.inputStream open];
        [self.outputStream open];

        [[self rac_signalForSelector:@selector(stream:handleEvent:)
                        fromProtocol:@protocol(NSStreamDelegate)]
            subscribeNext:^(RACTuple *tuple)
            {
                NSStream *aStream = (NSStream *)tuple.first;
                NSStreamEvent *eventCode = (NSStreamEvent *)tuple.second;
                // check eventCode here
                NSArray *data = read_InputStream;
                [theSubscriber sendNext:data];
            }];

        return nil;
    }];
}

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
}

When using rac_signalForSelector, the signal will pass the arguments from the method through as a tuple which you can then look at to decide what action to take.

Depending on what you're trying to achieve here, there are probably more elegant reactive solutions, but rac_signalForSelector at least solves the problem of needing the subscriber property.

Upvotes: 1

Related Questions