Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to observe Bool properties with RxSwift?

I have two Bool properties in my VC.swift:

var isRecording = false
var isPlaying = false

In the viewDidLoad() method I have such code:

let observable = Observable.combineLatest(self.rx_observe(Bool.self, "isRecording"), self.rx_observe(Bool.self, "isPlaying")) { (val1, val2) -> Void in
        if(val1 == false && val2 == false){
            self.recordButton.enabled = true
            self.playButton.enabled = true
            self.recordButton.setImage(UIImage(named: "record"), forState: UIControlState.Normal)
            self.playButton.setImage(UIImage(named: "play"), forState: UIControlState.Normal)
        } else if(val1 == true && val2 == false){
            self.recordButton.enabled = true
            self.recordButton.setImage(UIImage(named: "stop"), forState: UIControlState.Normal)
            self.playButton.enabled = false
        } else if(val1 == false && val2 == true){
            self.recordButton.enabled = false
            self.playButton.enabled = true
            self.playButton.setImage(UIImage(named: "stop"), forState: UIControlState.Normal)
            self.recordButton.setImage(UIImage(named: "record"), forState: UIControlState.Normal)
        }
    }.observeOn(MainScheduler.instance)
    addSubscription(observable.subscribe())

The function addSubscription(:_) adds subscription to DisposableBag. The problem is that the code in the closure works only once. It does not work when properties "isRecording" and "isPlaying" change. What should I do if I want this code to be performed after I have these bool properties changed?

like image 639
Marina Avatar asked Oct 16 '25 10:10

Marina


2 Answers

Don't use Bool and rx_observe. Instead, use a Subject such as Variable<Bool>.

let isRecording = Variable(false)
let isPlaying = Variable(false)

let observable = Observable.combineLatest(isRecording.asObservable(), isPlaying.asObservable()) { (val1, val2) -> Void in
    //...

However, to answer your question as to why it doesn't work with rx_observe, it's because rx_observe relies on the property being KVO compliant. If you used the dynamic keyword in front of your property definitions, it would have worked: dynamic var isRecording = false. However, you should really be using a Subject such as Variable. Check out the playground page dealing with Subjects in the RxSwift repo. It gives an example of each type.

like image 108
solidcell Avatar answered Oct 19 '25 00:10

solidcell


With latest RxSwift 5.0+ you can use BehaviorRelay

let isLoading = BehaviorRelay<Bool>(value: false)

And you can observe it's value as below:

isLoading.asObservable().subscribe { status in
                print(status)
            }.disposed(by: disposeBag)
like image 43
Parth Adroja Avatar answered Oct 18 '25 23:10

Parth Adroja



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!