iosobjective-cmvvmracsignal

Subscribe issue with RACSignal


I am using the MVVM paradigm in my iOS with RACSignal as well. So far things have worked out great. However I am experiencing a problem when subscribing to signals. On the first subscription things work fine. However further subscriptions don't.

The code

In my viewModel I have an RACSignal declared like this:

viewModel.h

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

viewModel.m

@property (nonatomic, readwrite, strong) RACSubject *updatedContentSignal;

It is then initialised like so in the viewModel's designated initialiser:

self.updatedContentSignal = [[RACSubject alloc]init];

Then when I actually use the signal in the viewModel I do this sort of thing: Where needed in various places in the viewModel - typically within a web service block method

[(RACSubject *)self.updatedContentSignal sendNext:nil];
[(RACSubject *)self.updatedContentSignal sendCompleted];
[(RACSubject *)self.updatedContentSignal sendError:error];

In the viewController I subscribe to signal like so:

[self.viewModel.updatedContentSignal subscribeNext:^(id x) {

    } error:^(NSError *error) {


    } completed:^{


    }];

I subscribe once to the signal on viewDidLoad

So all works on the first viewDidLoad call

The problem

When I navigate away from the viewController and come back to it viewWillAppear is called, and the viewModelfires off various methods that trigger the signal:

  [(RACSubject *)self.updatedContentSignal sendNext:nil];
    [(RACSubject *)self.updatedContentSignal sendCompleted];
    [(RACSubject *)self.updatedContentSignal sendError:error];

However the viewController no longer receives the signal. It seems it only works not he first subscription.

Is there a way to have it that the signal will continue to work each time one of the updateContent signal is call/ fired?


Solution

  • As your code is not very comprehensive I can only say a signal will be dismissed as soon as it is completed (either via sendCompleted: or sendError:).

    So if you want to continue you'll have to only use sendNext:.
    Only use sendCompleted, in case you want to show, that this is no longer used.

    SendError: is used, in case you receive an error. so in your web service block you'd need something like:

    if(!error) {
        sendNext:xxx; 
    } else {
        sendError:error;
    }