Search code examples
reactive-cocoaracsignal

RACSignal and replayLazily. How can I handle errors?


This works brilliantly...

@interface Hello : NSObject

@property (nonatomic, strong, readonly) RACSignal *signal;

@end

@interface Hello ()

@property (nonatomic, strong, readwrite) RACSignal *signal;

@end

@implementation Hello

- (instancetype)init
{
    self = [super init];
    if(self)
    {
        self.signal = [[[self createSignal] replayLazily];
    }
    return self;
}

- (RACSignal *)createSignal
{
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [[Service getInstance] getProducts:^(NSArray *products) {
            [subscriber sendNext:products];
            [subscriber sendCompleted];
        } error:^(NSError *error) {
            [subscriber sendError:error];
        }];
    }];
}

@end

...as long as there are NO errors.

I guess this is because the sourceSignal for the RACMulticastConnection sent an error.

The behavior I want to have

  • start the request if first subscriber
  • if a second subscriber subscribes – hook on to the ongoing request
  • if the request is successful any new subscribers will get the result from the succesful request
  • if the request is not successful new subscriptions will trigger a new fetch – multicasted

Solution

  • Re-create your signal when there is a error

    - (RACSignal *)createSignal
    {
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            [[Service getInstance] getProducts:^(NSArray *products) {
                [subscriber sendNext:products];
                [subscriber sendCompleted];
            } error:^(NSError *error) {
                [subscriber sendError:error];
                self.signal = [[[self createSignal] replayLazily];
            }];
        }];
    }