Simple observable struct with RxSwift?

空扰寡人 提交于 2019-12-01 10:09:50

问题


I'm trying to come up with a simple observable object in Swift and thought to use RxSwift. I couldn't find a simple example to do something like this:

protocol PropertyObservable {
  typealias PropertyType
  var propertyChanged: Event<(PropertyType, Any)> { get }
}

class Car: PropertyObservable {
  typealias PropertyType = CarProperty
  let propertyChanged = Event<(CarProperty, Any)>()

  dynamic var miles: Int = 0 {
    didSet {
      propertyChanged.raise(.Miles, oldValue as Any)
    }
  }

  dynamic var name: String = "Turbo" {
    didSet {
      propertyChanged.raise(.Name, oldValue as Any)
    }
  }
}

The above is pure Swift solution for observables from this blog post; I really like how it's a protocol-based solution and not invasive. In my case, I have an object in my project where each property is set asynchronously under the hood (bluetooth device). So I need to observe/subscribe to the changes instead of getting/setting the properties in real-time.

I keep hearing RxSwift will do just that and more. However, I can't find a simple example to match above and beginning to think RxSwift is overkill for my need? Thanks for any help.


回答1:


Easiest way to quickly make this observable with RxSwift would probably be to use the RxSwift class Variable (all code here is untested off the top of my head):

import RxSwift

class Car {

  var miles = Variable<Int>(0)

  var name = Variable<String>("Turbo")

}

This enables you to observe the values by subscribing to them:

let disposeBag = DisposeBag()
let car = Car
car.name.asObservable()
  .subscribeNext { name in print("Car name changed to \(name)") }
  .addToDisposeBag(disposeBag) // Make sure the subscription disappears at some point.

Now you've lost the old value in each event. There are of course numerous ways to solve this, the RxSwifty way would probably be to add a scan operation to your element sequence, which works a lot like reduce does on a normal Array:

car.name.asObservable()
  .scan(seed: ("", car.name.value)) { (lastEvent, newElement) in
    let (_, oldElement) = lastEvent
    return (oldElement, newElement)
  }
  .subscribeNext { (old, new) in print("Car name changed from \(old) to \(new)") }
  .addToDisposeBag(disposeBag)


来源:https://stackoverflow.com/questions/36460542/simple-observable-struct-with-rxswift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!