Swift 如果“下一个”事件已经发生,我如何观察信号并立即接收到它?

Swift 如果“下一个”事件已经发生,我如何观察信号并立即接收到它?,swift,swift2,reactive-programming,reactive-cocoa,reactive-cocoa-3,Swift,Swift2,Reactive Programming,Reactive Cocoa,Reactive Cocoa 3,我正在尝试包装一个API调用,该调用在网络请求后初始化一个对象。我不希望网络请求发生在每个新的观察者身上,因此据我所知,我不应该使用SignalProducer。但是,通过使用单个信号,只有首次使用该信号的用户才会收到下一个事件,而任何较新的订户都不会收到当前值。我应该怎么做?我可能对RAC做了一些根本性的错误 extension SparkDevice { static func createMainDeviceSignal() -> Signal<SparkDevice,

我正在尝试包装一个API调用,该调用在网络请求后初始化一个对象。我不希望网络请求发生在每个新的观察者身上,因此据我所知,我不应该使用
SignalProducer
。但是,通过使用单个
信号
,只有首次使用该信号的用户才会收到
下一个
事件,而任何较新的订户都不会收到当前值。我应该怎么做?我可能对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()
    }
 }
扩展SparkDevice{
静态函数createMainDeviceSignal()->信号{
返回信号{
陷入
SparkCloud.sharedInstance().getDevices{(sparkDevices:[AnyObject]!,错误:NSError!)->在中无效
如果let error=error{
sink.sendFailed(错误)
}
否则{
如果让设备=sparkDevices as?[SparkDevice]{
如果devices.count>0{
sink.sendNext(设备[0])
}
}
}
}
归零
}
}
}
类设备访问{
让设备发出信号:信号
init(){
self.deviceSignal=SparkDevice.createMainDeviceSignal()
}
}
我考虑过使用
MutableProperty
,但这似乎需要一个默认属性,这似乎没有什么意义


我应该怎么做呢?

你需要的是多播。然而,
ReactiveCocoa
3/4并没有提供一种简单的方法来实现这一点(与Rx相反),因为它们通常会导致大量的复杂性

有时它确实是必要的,如您的示例中所示,并且可以使用
属性类型
轻松实现

我首先创建发出请求的冷信号。必须是一个
信号发生器

private func createMainDeviceSignalProducer() -> SignalProducer<SparkDevice, NSError> {
    return SignalProducer { observer, _ in
        ....
    }
}

现在,
DeviceAccess.deviceProducer
将重播底层生产者发出的值,而不是重复副作用。但是请注意,它不是懒惰的:底层的
SignalProducer
将立即启动。

使用这种方法,您可以对访问DeviceAccess.deviceProducer进行评论。但这应该如何从中访问?单身汉
DeviceAccess.sharedInstance.deviceProducer.startWithNext{…}
所有希望观察相同结果的实例,以及在发生更改时如何重新加载该
SparkDevice
?(从后端重新获取)
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
    }
 }