0

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?

halfer
  • 19,824
  • 17
  • 99
  • 186
Robert J. Clegg
  • 7,231
  • 9
  • 47
  • 99
  • 1
    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: else sendError:error; – Jan Dec 03 '15 at 12:01
  • Thanks for the informative post. You are correct that its sending complete that effectively kills the signal until the next time I recreate it when I show a new viewController with it. If you could put your comment as an answer, I'll accept it. Thanks @Dimitri – Robert J. Clegg Dec 15 '15 at 07:36

1 Answers1

1

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;
}
Jan
  • 1,827
  • 2
  • 16
  • 29