Flipper
Flipper

Reputation: 1107

ReactiveCocoa, RACCommand show message or execute segue after completed

I'm using RACCommand for my UI button click event. I'm using MVVM architecture. In my ViewModel I have this:

@property (strong, nonatomic) RACCommand *executeRegistration;

Inside "init" I have this:

self.executeRegistration = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input)
{
    return  [self executeSearchSignal];
}];

Execute search signal is this:

- (RACSignal *)executeSearchSignal {
return [[[self.services insertUserRegistration]
         registerUserName:self.userName]
         logAll];
}

My "[self.services insertUserRegistration] registerUserName:self.userName" is this:

 @weakify(self);
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber)
{
    @strongify(self);

    Manager *manager = [Manager sharedManager];
    manager._delegate = self;

    RACSignal *successSignal =
    [self rac_signalForSelector:@selector(manager:didSuccesWithoutError:)
                   fromProtocol:@protocol(ManagerDelegate)];

    RACSignal *failSignal =
    [self rac_signalForSelector:@selector(manager:didFailWithError:)
                   fromProtocol:@protocol(ManagerDelegate)];

    [[successSignal map:^id(RACTuple *tuple)
    {
        return tuple.second;
    }] subscribeNext:^(id x) {
        [subscriber sendNext:x];
        [subscriber sendCompleted];
    }];

    [[failSignal map:^id(RACTuple *tuple)
      {
          return tuple.second;
      }] subscribeNext:^(id x) {
          [subscriber sendError:x];
      }];

    [manager insertUserRegistration:name];
    return nil;
}];

My ViewController has this in BindViewModel method:

[self.finishRegistrationButton.rac_command.executionSignals subscribeNext:^(RACSignal *loginSignal) {
    // Log a message whenever we log in successfully.
    [loginSignal subscribeCompleted:^{
        NSLog(@"I'm here.");
    }];
}];

self.finishRegistrationButton.rac_command = self.viewModel.executeRegistration;

With my "logAll" atribute I can see everything executing, the problem is it never goes into subsrcibeCompleted after everything is ok. I want to show error message if there is an error or perform segue if everything is ok. What am I doing wrong? Can you please explain how to to that properly? I'm stuck here for quite some time now.

Upvotes: 0

Views: 1059

Answers (2)

Flipper
Flipper

Reputation: 1107

I did it. RACCommand 'does not have subscribeError'. Signals sent does not include error events. There is special property 'errors'. In that property, every signal that sends error sends is as 'next'. so, solution is to use this:

[self.executeRegistration.executionSignals subscribeNext:^(RACSignal *signal){
[signal subscribeCompleted:^{
     NSLog(@"Registered");
  }];
}];

[self.executeRegistration.errors subscribeNext:^(id x) {
    NSLog(@"Error");
}];

This is ok. There is no need to subscribeNext if you don't want every new value. This is actually really cool stuff, but I've read that it is too confusing why it is not sending errors as in classic implementation (it was for me :)). That will be included in 3.0 if I'm not mistaken.

Upvotes: 2

Charles Maria
Charles Maria

Reputation: 2195

self.finishRegistrationButton.rac_command.executionSignals returns a signal of signals, so you'll want to make use of switchToLatest, like so:

self.finishRegistrationButton.rac_command.executionSignals.switchToLatest

This function intercepts signals and switches to the latest received, sending next, errors and completes from that signal instead of the signal operated on. It's very handy for operations that send signals over time.

This code will only work for executionSignals that hold a single signal, if you want multiple targets then you'll need something a bit more complex. If you ever need to change your code to work that way, you might want to have a look at flattenMap:.

Upvotes: 0

Related Questions