Why the signal is called twice in ReactiveCocoa?

ios, objective-c, reactive-cocoa, reactive-programming

Solution

This happens because the block passed to `+[RACSignal createSignal:]` executes whenever a subscription to the signal is made, and your code creates two separate subscriptions:

[login subscribeCompleted:^{ ... }];

[login subscribeError:^(NSError *error) { ... }];

If you only want to create a single subscription, use the method `-[RACSignal subscribeError:completed:]`:

[login subscribeError:^(NSError *error) {
        [SVProgressHUD dismiss];

        [AppUrls alertError:LOC_ERROR_LOGING msg:error.userInfo[@"error"]];
    }
    completed:^{
        [[NSNotificationCenter defaultCenter]
         postNotificationName:NOTIFY_LOGIN_CHANGED
         object:self];

         [SVProgressHUD showSuccessWithStatus:LOC_OK];


         [self cancelForm];
    }];

Problem

I'm implementing my first code with https://github.com/ReactiveCocoa/ReactiveCocoa. Is for login a user. The line `[subscriber sendNext:user];` is called twice, but I expect to be only one. And the map is not called at all (so autologin is never called) This is my implementation: ``` -(RACSignal *) login:(NSString *)email pwd:(NSString *)pwd { DDLogInfo(@"Login user %@", email); RACSignal *login = [RACSignal createSignal:^ RACDisposable *(id<RACSubscriber> subscriber) { [PFUser logInWithUsernameInBackground:email password:pwd block:^(PFUser *user, NSError *error) { if (error) { [subscriber sendError:error]; } else { [subscriber sendNext:user]; [subscriber sendCompleted]; } }]; return nil; }]; [login map:^(PFUser *user) { return [self autoLogin:user]; }]; return login; } ``` Is called this way: ``` NSString *email = data[@"email"]; NSString *pwd = data[@"pwd"]; [SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeBlack]; RACSignal *login = [[SyncEngine server] login:email pwd:pwd]; [login subscribeCompleted:^ { [[NSNotificationCenter defaultCenter] postNotificationName:NOTIFY_LOGIN_CHANGED object:self]; [SVProgressHUD showSuccessWithStatus:LOC_OK]; [self cancelForm]; }]; [login subscribeError:^(NSError *error) { [SVProgressHUD dismiss]; [AppUrls alertError:LOC_ERROR_LOGING msg:error.userInfo[@"error"]]; }]; ```

Original source