How to Observe Object's Property in Rxswift

How to observe object's property in RxSwift?

Actually you should declare currentTemperature as Variable to observe the value changes. Your Forecast will become as this

class Forecast {

let city: City

var currentTemperature: Variable<String> = Variable("0")

init(city: City) {
self.city = city
}

func loadForecast() {
self.currentTemperature.value = "+10"
}

}

So now you can subscribe to listen the changes in currentTemperature as below,

class ForecastViewModel {

fileprivate let variableForecast: Variable<Forecast>

var navigationTitle: Observable<String> {
return Observable.just("No name")
}

init(forecast aForecast: Forecast) {
self.variableForecast = Variable(aForecast)

self.variableForecast.value.currentTemperature.asObservable().subscribe(onNext: { (value) in
print(value)
})

variableForecast.value.currentTemperature.value = "-15"
variableForecast.value.loadForecast()
}

}

How to observe array property changes in RxSwift

Most of the time, if you have control of the backing variable, you would prefer Variable to using rx_observe.

class ViewController: UIViewController {
var myArray : Variable<NSArray>!
}

The first time you'll use myArray, you would asign it like so

myArray = Variable(["a"])

Then, if you want to change its value

myArray.value = ["b"]

And you can easily observe its changes, using

myArray.asObservable().subscribeNext { value in
// ...
}

If you really want to use rx_observe (maybe because the variable is used elsewhere in your program and you don't want to change the API of your view controller), you would need to declare myArray as dynamic (another requirement is that the hosting class is a child of NSObject, here UIViewController satisfies this requirement). KVO is not implemented by default in swift, and using dynamic ensures access is done using the objective-c runtime, where KVO events are handled.

class ViewController: UIViewController {
dynamic var myArray: NSArray!
}

Documentation for this can be found here

RxSwift `observeWeakly` on certain UIView properties fails while `observe` does work

After encountering this issue again it actually got fixed by just not even trying to observe the UIView's properties. Instead I observe the underlaying CALayer for any changes, which after some basic testing seems to do the trick.

extension Reactive where Base: UIView {
var observeAlpha: Observable<Float?> {
get {
return base.layer.rx.observeWeakly(Float.self, "opacity")
.catchAndReturn(1.0)
.startWith(base.layer.opacity)
}
}


var observeIsHidden: Observable<Bool?> {
get {
return base.layer.rx.observeWeakly(Bool.self, "hidden")
.catchAndReturn(false)
.startWith(base.layer.isHidden)
}
}
}

RxSwift : Observe each element observable property in observable array

You can use Observable.combineLatest to combine all latest event in array's element's property

Here is the solution that worked for me.

class Player {
let stamina = Variable(0)
}

// ViewController
let disposeBag = DisposeBag()

// Array
let playerList: Variable<[Player]> = Variable([])

// Observing each player stamina at once
playerList.asObservable()
.flatMapLatest { players -> Observable<[Int]> in
let playerStaminaObservableList = players.map { $0.stamina.asObservable() }
return Observable.combineLatest { playerStaminaObservableList }
}
.subscribe(onNext: {
print("List of playerStamina: \($0)")
})
.disposed(by: disposeBag)

Feel free to correct any mistake.

How to observe Bool properties with RxSwift?

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.



Related Topics



Leave a reply



Submit