0

Short version: Is it possible to use RACMulticastConnection in the same way as NSNotificationCenter? I mean to keep the subscribed blocks valid even for another call [connection connect]?

Long version: Among different subscribers I share a reference to RACMulticastConnection. Those who initiate the request pass loginRequest!=nil and those subscribers who want just listen use loginRequest==nil:

RACMulticastConnection *connection = [self.appModel loginRequest:loginRequest];
[connection connect]; //I initiate the request


[connection.signal subscribeNext:^(RACTuple* responseTuple) {

} error:^(NSError *error) {

} completed:^{

}];

In other modul I just subscribe and listen:

RACMulticastConnection *connection = [self.appModel loginRequest:nil];
[connection.signal subscribeNext:^(RACTuple* responseTuple) {

} error:^(NSError *error) {

} completed:^{

}];

When I call the [connection connect]; everything works fine. The subscribers are notified. But if I want to repeat the request to the server again with [connection connect]; I just receive successful signal with the old responses.

Basic idea is I want to create RACMulticastConnection once and share it for potential subscribers. Those who listen pass nil arguments, those who initiate the request pass not nil argument and call [connection connect]; But it does not trigger the block defined in RACSignal createSignal:.

The RACSignal is created just once when RACMulticastConnection does not exist. self.loginRequestConnection is property of model. The property is shared in the application to subscribers:

- (RACMulticastConnection*) loginRequest:(LoginRequest*)request {

    self.loginRequest = request;

    if(! self.loginRequestConnection) { // the instance of RACMulticastConnection shared among the subscribers

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

            __block Response* blockResponse = nil;

            @strongify(self);

            [_serviceClient login:self.loginRequest success:^(TSNApiResponse *response, TSNError *error) {

                blockResponse = response;
                [subscriber sendNext:RACTuplePack(response, error)];
                [subscriber sendCompleted];

            } failure:^(TSNError *error) {

                [self cleanUpRequestOnError:error subscriber:subscriber blockResponse:blockResponse blockRequest:self.loginRequest];

                [subscriber sendError:error];
            }];

            return [RACDisposable disposableWithBlock:^{

                [_serviceClient cancelRequest:self.loginRequest];
            }];

        }];

        self.loginRequestConnection = [networkRequest multicast:[RACReplaySubject subject]];
    }

    return self.loginRequestConnection;
}

Is there any correct way how to make the connection trigger again the block in the RACSignal? Thank you.

Vladimír Slavík
  • 1,727
  • 1
  • 21
  • 31

1 Answers1

1

I have used FBKVOController. The code done with FBKVOController is fraction of the implementation done with ReactiveCocoa:

- (void) loginRequest:(TSNLoginRequest*)request {

    [_serviceClient login:request success:^(TSNApiResponse *response, TSNError *error) {

        self.loginResponseTuple = [TSNResponseTuple responseTuple:response error:error];

    } failure:^(TSNError *error) {

        self.loginResponseTuple = [TSNResponseTuple responseTuple:nil error:error];

   }];
}

Issuing the request:

[self.appModel loginRequest:loginRequest];

Observing the response:

[_KVOController observe:self.appModel keyPath:@"loginResponseTuple" options:NSKeyValueObservingOptionNew block:^(TSNStartupScreenViewModel* observer, TSNAppModel* observed, NSDictionary *change) {

    TSNResponseTuple* responseTuple = change[NSKeyValueChangeNewKey];

    @strongify(self);
    if([responseTuple.error isError]) {

        [TSNAppUtilities showError:(TSNError *)(responseTuple.error) completion:^(OHAlertView *alert, NSInteger buttonIndex) {

            if(buttonIndex == alert.firstOtherButtonIndex) {

                // ... process selection
            }
        }];
    } 
}];
Vladimír Slavík
  • 1,727
  • 1
  • 21
  • 31