Odrakir
Odrakir

Reputation: 4254

ReactiveCocoa: Manually sending event

Ok, I have a signal that sends an event when a certain method of a protocol gets called in response to some data getting retrieved from the server:

self.dataReceivedSignal = [[self rac_signalForSelector:@selector(didReceiveData:) fromProtocol:@protocol(DataServiceDelegate)] mapReplace:@YES];

This signal is then used to fire another signal that formats and returns the data:

- (RACSignal *)dataSignal
{
    return [RACSignal combineLatest:@[self.dataReceivedSignal] reduce:^id(NSNumber * received){
        ...
        return my_data;
    }];
}

This view controller just listens to this second signal to get the data.

This works fine.

The problem is, the second time I enter this view controller, I don't want to load the data again, so I save it locally and do this:

if (!self.alreadyHasData) {
    self.dataService = [[DataService  alloc] init];
    self.dataService.delegate = self;
    [self.dataService getData];
} else {
    self.dataReceivedSignal = [RACSignal return:@YES];
}

In case I already have the data, I'm replacing the dataReceivedSignal with a new one that just sends @YES and completes.

This works too, but that if/else doesn't seem too functional to me. Is this the correct approach?

Thanks.

Upvotes: 1

Views: 550

Answers (1)

Gralex
Gralex

Reputation: 4485

First of all you can exchange combineLatest to map. If you want not reload data if it's already loaded, you can write something like this:

- (RACSignal *)dataSignal
{
    if (!_dataSignal) {
        RACMulticastConnection *dataConnection = [[self.dataReceivedSignal map:^id(NSNumber * received){
            /// ...
            return my_data;
        }] multicast:[RACReplaySubject replaySubjectWithCapacity:1]];

        // Only do all of the above after one subscriber has attached.
        _dataSignal = [RACSignal defer:^{
            [dataConnection connect];
            return dataConnection.signal;
        }];
    }
    return _dataSignal;
}

And don't matter how much subscribers signal will have, retrieve data block will be called only one time.

Simpler code = better code. I think you can solve task with simpler solution without RAC.

Upvotes: 1

Related Questions