1

I used to use ReactiveCocoa in Objective-C but I've since switched to RxSwift as I found it easier to understand than RAC4. However there's something I used to do in RAC that was useful:

@weakify(self);
[[RACCommand alloc] initWithEnabled:RACObserve(self, valid) signalBlock:^RACSignal *(id input) {
    @strongify(self);
    return [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

        //make network call

        //send responseObject to subscriber
        [subscriber sendNext:responseObject];

        [subscriber sendCompleted];
        return nil;
    }] materialize];
}];

This allowed me to subscribe to the command for it's executing state as well as its execution signals so that I could observe data that is returned from the call.

I'm not sure how to reproduce this with RxSwift Action. I am only able to subscribe to its executing observable:

    var loader: NotificationType?
    formButton.rx_action!.executing.subscribeNext({ [weak self] (executing) -> Void in
        if executing {
            loader = self?.showNotification(.Loading, title: self?.viewModel.loaderTitle.value, message: "Please wait".localized, timeout: -1)
        }
        else {
            if let loader = loader {
                loader.dismiss()
            }
        }
    }).addDisposableTo(disposeBag)

But I then have to create an additional PublishSubject to send my response data:

    viewModel.submitSubject.subscribe(onNext: { (response) -> Void in
        print(response)
        }, onError: { (error) -> Void in
            print(error)
        }, onCompleted: { () -> Void in
            //completed
        }) { () -> Void in
    }.addDisposableTo(disposeBag)

Is there a way to create a similar pattern in RxSwift with Action?

jwswart
  • 1,226
  • 14
  • 16

1 Answers1

0

This is possible with Action but currently it's not straightforward. The problem is that to set an Action property on an object, that object's property must declare the full generic type of Action, which is typically Action<Void, Void> (this is typealias'd to CocoaAction). The two generic types are the input and output, respectively. We chose Void because it represents the fact that work has been done, but doesn't care about what work it is. It's not a perfect solution, since it leads to the problem you're currently facing, and I'm sorry about that.

You want to subscribe to the output of the action's signal, but due to using Void as the output, you can't. The PublishSubject approach you have here is one workaround, another solution would be to use the Void as an output type; you could use errors to indicate failure and Void() to indicate success, but all the work you want to do would need to be encapsulated in the Action's signal. I'd probably use the second approach, but it might not work in all cases.

We have an issue to deal with this but I haven't had time to give it much thought. Any suggestions or resources you have would be awesome

Ash Furrow
  • 12,391
  • 3
  • 57
  • 92