Using RACCommand and creating custom RACSignals in Objective C

2 comments on Using RACCommand and creating custom RACSignals in Objective C

Written by

in

To bind some action to the button click one can use just a custom RACSignal. But then you have to add three more things in every case:
1. Disable button, while action is performing;
2. Show, that action is in progress;
3. Disable button, if input is incorrect and button should not be able to be tapped.

Instead, if you use RACCommand, you get all these things in a box.

Let’s say, we want to bind RACCommand verifyPhoneCommand to a button. We can create a command in a lazy property in a ViewModel:

- (RACCommand *)verifyPhoneCommand
{
    if (! _verifyPhoneCommand) {
        _verifyPhoneCommand = [[RACCommand alloc] initWithEnabled:self.phoneValidSignal
                                                      signalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
                                                          return [self verifyPhone];
                                                      }];
    }
    return _verifyPhoneCommand;
}

Here phoneValidSignal is this signal, that is formed by observing a phone variable:

- (RACSignal *)phoneValidSignal
{
    if (!_phoneValidSignal) {
        _phoneValidSignal = [RACObserve(self, phone) map:^id(NSString *phone) {
            return @(phone.length > 0);
        }];
    }
    return _phoneValidSignal;
}

We pass a RACSignal verifyPhone to the RACCommand to do a job:

- (RACSignal *)verifyPhone
{
    return [RACSignal createSignal:^RACDisposable * _Nullable(id  _Nonnull subscriber) {

        [[PhoneManager sharedManager]
         requestVerifyPhone:self.phone
         success:^{

             [subscriber sendNext:@(YES)];
             [subscriber sendCompleted];
             
         } failure:^(NSError *error) {
             
             [subscriber sendError:error];
             
         }];
        
        return nil;
    }];
}

This is how we bind a RACCommand to a button:

self.smsRequestButton.rac_command = self.viewModel.verifyPhoneCommand;

To track execution of a RACCommand and show an activity indicator we can use executing property:

[self.viewModel.verifyPhoneCommand.executing subscribeNext:^(NSNumber*  _Nullable x) {
        if (x.boolValue) {
            [self.spinnerView startAnimating];
        }
        else {
            [self.spinnerView stopAnimating];
        }
    }];

If errors happen during RACCommand execution we can process those errors:

[self.viewModel.verifyPhoneCommand.errors subscribeNext:^(NSError * _Nullable error) {
        [ErrorUtil showError:error from:self onRepeat:^{
            
        }];
    }];

Comments

2 responses to “Using RACCommand and creating custom RACSignals in Objective C”

  1. Sophie Avatar
    Sophie

    Could you show one more example, please? Thanks

  2. Aleksandr Avatar
    Aleksandr

    The article is helpful. Thanks to the author!

Leave a Reply

Your email address will not be published. Required fields are marked *