sol*_*ell 2 reactive-programming reactive-cocoa swift reactive-cocoa-3 swift2
我正在尝试包装一个在网络请求后初始化对象的API调用.我不希望每个新观察者都发生网络请求,因此据我所知,我不应该使用SignalProducer.但是,通过使用单个Signal,只有它的第一次使用将接收next事件,而任何较新的订户将永远不会收到当前值.我该怎么做?我可能正在做一些与RAC根本错误的事情.
extension SparkDevice {
static func createMainDeviceSignal() -> Signal<SparkDevice, NSError> {
return Signal {
sink in
SparkCloud.sharedInstance().getDevices { (sparkDevices: [AnyObject]!, error: NSError!) -> Void in
if let error = error {
sink.sendFailed(error)
}
else {
if let devices = sparkDevices as? [SparkDevice] {
if devices.count > 0 {
sink.sendNext(devices[0])
}
}
}
}
return nil
}
}
}
class DeviceAccess {
let deviceSignal: Signal<SparkDevice, NSError>
init() {
self.deviceSignal = SparkDevice.createMainDeviceSignal()
}
}
Run Code Online (Sandbox Code Playgroud)
我考虑使用MutableProperty,但这似乎需要一个默认属性,这似乎没有意义.
我该怎么做呢?
你需要的是多播.然而,ReactiveCocoa3/4并没有提供一种简单的方法(与Rx相反),因为它们经常导致大量的复杂性.
有时它确实是必要的,如在您的示例中,并且可以使用a轻松实现PropertyType.
我首先创建发出请求的冷信号.那必须是SignalProducer:
private func createMainDeviceSignalProducer() -> SignalProducer<SparkDevice, NSError> {
return SignalProducer { observer, _ in
....
}
}
Run Code Online (Sandbox Code Playgroud)
如果您按原样公开,则每次生成此生成器时都会发生副作用start.为了multicast这些值,你可以在属性包装它和暴露property的producer,而不是:
public final class DeviceAccess {
public let deviceProducer: SignalProducer<SparkDevice, NoError>
private let deviceProperty: AnyProperty<SparkDevice?>
init() {
self.deviceProperty = AnyProperty(
initialValue: nil, // we can use `nil` to mean "value isn't ready yet"
producer: SparkDevice.createMainDeviceSignal()
.map(Optional.init) // we need to wrap values into `Optional` because that's the type of the property
.flatMapError { error in
fatalError("Error... \(error)") // you'd probably want better error handling
return .empty // ignoring errors, but you probably want something better.
}
)
self.deviceProducer = deviceProperty
.producer // get the property producer
.ignoreNil() // ignore the initial value
}
}
Run Code Online (Sandbox Code Playgroud)
现在DeviceAccess.deviceProducer将重放底层生成器发出的值,而不是重复的副作用.但请注意,它并不是懒惰的:底层SignalProducer将立即开始.
| 归档时间: |
|
| 查看次数: |
989 次 |
| 最近记录: |