0

I am trying to detect clicks on an UIElement like a button using Reactive Cocoa, using RAC for the first time in MVVM architecture.

I set the rac_command for my button in my ViewController.

    addContactBtn.rac_command = viewModel.addContact

My ViewModel does the following:

func init(){
self.addContact = RACCommand() {
  (any:AnyObject!) -> RACSignal in
  return RACSignal.createSignal({
    (subscriber: RACSubscriber!) -> RACDisposable! in
    print("creating viewModel")
    let viewModel = ContactAddViewModel(services: self.services)
    self.services.pushViewModel(viewModel)

    return RACDisposable(block: {
    })
  })
}
}

However, the command is executed only once and then the button is in disabled state when I pop the view controller and come back to original viewController. How can detect the button click any number of times?

Ajax
  • 1,689
  • 4
  • 20
  • 29

1 Answers1

1

Obviously, you missed something and had a simple mistake.

RACCommand expects to a signal which will be alive when the button clicked and be disposed after click-business-logic (like create viewModel, then pushViewModel in the above) executed. That is to say each button clicking-event associates a signal, not shares one unique signal, but has common signal inner logic. If a signal does not achieve completion or error, the responding clicking-event is not finished such that the button is disabled.

The below modified codes could be correct.

func init(){
    self.addContact = RACCommand() {
        (any:AnyObject!) -> RACSignal in
        return RACSignal.createSignal({
            (subscriber: RACSubscriber!) -> RACDisposable! in
            print("creating viewModel")
            let viewModel = ContactAddViewModel(services: self.services)
            self.services.pushViewModel(viewModel)

            // if you like to expose some value
            // subscriber.sendNext(value)

            subscriber.sendCompleted()  // which makes clicking-event finished

            // maybe error occurs
            // subscriber.sendError()

            return RACDisposable(block: {
            })
        })
    }
}

I would like to advise you to checkout CocoaAction and Action in ReactiveSwift, which are replacement for RACCommand of legacy ReactiveObjC.

Qinghua
  • 351
  • 3
  • 10
  • I couldn't find good documentation with examples to get started with ReactiveSwift or RAC 5.0. Any leads would be appreciated. – Ajax Jan 06 '17 at 10:31
  • @Ajax I could not help more, maybe official documentation is a good choice which is extremely helpful. – Qinghua Jan 06 '17 at 10:36