swiftmvvmreactivekit

Bond/ReactiveKit - Temporarily suspend observing events and start observing again (but see events that were missed)


I'm starting to use Bond to implement a basic MVVM pattern in an app and have a scenario where I would like to temporarily suspend the observing of events on an Observable (via a flag).

I would then like to resume the observing of events, but also want to "replay/resend" the events to my observers which may have been missed during the suspension period.

I have found the pausable(by:) function on an Observable which works well for the temporary suspension of the observing of events, but am not sure how to "replay/resend" any events after reenabling the observation.

An cut-down example of what I'm trying to do is this :-

Code :-

class MyViewController: UIViewController {
    let viewModel = MyViewModel()
    let shouldUpdate = Observable(true)

    @IBOutlet weak var label: UILabel!

    @IBOutlet weak var changeMessageButton: UIButton!
    @IBOutlet weak var stopChangingLabelTextButton: UIButton!
    @IBOutlet weak var startChangingLabelTextButton: UIButton!

    override func viewDidLoad() {
       viewModel.message.pausable(by: shouldUpdate).bind(to: label.bnd_text)

       changeMessageButton.bnd_tap.observe { _ in
           viewModel.message.value = "Changing Message"
       }

       stopChangingLabelTextButton.bnd_tap.observe { _ in
           shouldUpdate.value = false
       }

       startChangingLabelTextButton.bnd_tap.observe { _ in
           shouldUpdate.value = true
           // DO SOMETHING TO BE ABLE TO "REPLAY/RESEND" ANY EVENTS TO viewmodel.message 
       }
    }
}

class MyViewModel {
   let message = Observable<String>("Original Value")
}

What would be the best way to tackle this?


Solution

  • Yes, pausable will ignore and omit events during the paused state. If you're ok with replaying only the latest value, you could flat map shouldUpdate like this:

    shouldUpdate.flatMapLatest { shouldUpdate -> SafeSignal<String> in 
        if shouldUpdate {
          return viewModel.message.toSignal()
        } else {
          return .never()
        }
    }.bind(to: label.bnd_text)
    

    Whenever shouldUpdate emits an event, it will either start propagating viewModel.message or nothing. Whenever it starts propagating viewModel.message it will also receive latest value since Observable always replays latests to new observers.

    Please make sure you do import ReactiveKit.