Combining multiple signals not working with Reactive Cocoa

I follow this guide: http://www.raywenderlich.com/62699/reactivecocoa-tutorial-pt1 . It works for username and password fields.

I am trying to create a registration form that contains three fields: email, password, confirmPassword.

I confirmed the email address (works fine) I confirmed the password as follows:

the password must be at least 6 characters, and both the password and confirmPassword must be the same.

Here is my code:

RACSignal *validEmailSignal =
[emailTextField.rac_textSignal
 map:^id(NSString *text) {
     return @([text isValidEmailAddress]);
 }];

RACSignal *validPasswordSignal =
[passwordTextField.rac_textSignal
 map:^id(NSString *text) {
     return @([text isEqualToString:self.confirmPasswordTextField.text] && text.length >5);
 }];

RACSignal *validConfirmPasswordSignal =
[confirmPasswordTextField.rac_textSignal
 map:^id(NSString *text) {
     return @([text isEqualToString:self.passwordTextField.text] && text.length >5 );
 }];

[[validEmailSignal
  map:^id(NSNumber *emailValid) {
      return [emailValid boolValue] ? [UIColor greenColor] : [UIColor redColor];
  }]
 subscribeNext:^(UIColor *color) {
     emailTextField.layer.borderColor=[color CGColor];
     emailTextField.layer.borderWidth= 1.0f;

 }];

[[validPasswordSignal
  map:^id(NSNumber *passwordValid) {
      return [passwordValid boolValue] ? [UIColor greenColor] : [UIColor redColor];
  }]
 subscribeNext:^(UIColor *color) {
     passwordTextField.layer.borderColor=[color CGColor];
     passwordTextField.layer.borderWidth= 1.0f;
     confirmPasswordTextField.layer.borderColor=[color CGColor];
     confirmPasswordTextField.layer.borderWidth= 1.0f;
 }];

[[validConfirmPasswordSignal
  map:^id(NSNumber *passwordValid) {
      return [passwordValid boolValue] ? [UIColor greenColor] : [UIColor redColor];
  }]
 subscribeNext:^(UIColor *color) {
     passwordTextField.layer.borderColor=[color CGColor];
     passwordTextField.layer.borderWidth= 1.0f;
     confirmPasswordTextField.layer.borderColor=[color CGColor];
     confirmPasswordTextField.layer.borderWidth= 1.0f;
 }];


RACSignal *signUpActiveSignal =
[RACSignal combineLatest:@[validEmailSignal, validPasswordSignal, validConfirmPasswordSignal]
                  reduce:^id(NSNumber *emailValid, NSNumber *passwordValid, NSNumber *confirmPasswordValid) {
                      return @([emailValid boolValue] && [passwordValid boolValue] && [confirmPasswordValid boolValue]);
                  }];


[signUpActiveSignal subscribeNext:^(NSNumber *signupActive) {

    NSLog(@"sign up button enabled : %hhd", [signupActive boolValue]);
    _signUpButton.enabled = [signupActive boolValue];
}];

Here, if I accept only the emailValid value, it sends 1 when it is valid. But if I include all three values, it always returns 0, even if all of them are valid.

Below are the simulator shots:

enter image description hereenter image description here

"", . "" .

+4
1

, :

and RACSignal, :

RACSignal *signUpActiveSignal = [[RACSignal combineLatest:@[validEmailSignal,
                                                            validPasswordSignal,
                                                            validConfirmPasswordSignal]] and];

RAC enabled ( , subscribeNext RAC, , CGColorRef id):

RAC(self.signUpButton, enabled) = signUpActiveSignal;

, . :

RACSignal *validPasswordSignal = [passwordTextField.rac_textSignal map:^id(NSString *text) {
    return @([text isEqualToString:self.confirmPasswordTextField.text] && text.length > 5);
}];

RACSignal *validConfirmPasswordSignal = [confirmPasswordTextField.rac_textSignal map:^id(NSString *text) {
    return @([text isEqualToString:self.passwordTextField.text] && text.length > 5);
}];

, passwordTextField , confirmPasswordTextField. , passwordTextField, confirmPasswordTextField. , ( ) :

------------------- initial state -------------------

           -------------
password: |             |   passwordValid: YES
           -------------

           -------------
 confirm: |             |   confirmValid: YES
           -------------

-------------- user types in a password --------------

           -------------
password: | asdf        |   passwordValid: NO
           -------------

           -------------
 confirm: |             |   confirmValid: YES (this will only recalculate when the confirm field changes, not when the password field changes)
           -------------


------- user types in the password confirmation -------

           -------------
password: | asdf        |   passwordValid: NO (this didn't recalculate because the contents of the password field didn't change)
           -------------

           -------------
 confirm: | asdf        |   confirmValid: YES
           -------------

! , . , , :

RACSignal *passwordsMatch = [RACSignal combineLatest:@[passwordTextField.rac_textSignal,
                                                       confirmPasswordTextField.rac_textSignal]
                                              reduce:(NSString *password, NSString *confirm) {
                                                  return @([password isEqualToString:confirm]);
                                              }];

RACSignal *isPasswordLongEnough = [passwordTextField.rac_textSignal map:^(NSString *text) {
    return @(text.length >= 6);
}];

:

RACSignal *signUpActiveSignal = [[RACSignal combineLatest:@[validEmailSignal,
                                                            isPasswordLongEnough,
                                                            passwordsMatch]] and];

, : " , , , ". !

+5

Source: https://habr.com/ru/post/1536567/


All Articles