简体   繁体   中英

ReactiveCocoa SignalProducer Explanation

Because of the behavior of start(), different Signals created from the producer may see a different version of Events. The Events may arrive in a different order between Signals, or the stream might be completely different!

Any example to above statement?

This is just speaking to the asynchronous nature of FRP and RAC. An example would be fetching large chunks of data from an API and doing something with the responses.

this is the purpose of flatMap and the FlattenStrategy methods ( .Latest will get you the data in the order it comes in, .Concat will preserve order)

An example would be retrieving an array of objects. .Latest will return each obj as it is received. .Concat will return the Array of objects in the original order. If one object takes a long time to download, the system will wait for it before proceeding to the other objects.

Another example is getting some JSON and handling it appropriately:

    func getData() -> SignalProducer<NSDictionary, NSError> {
        return SignalProducer { observer, _ in
                let data = someAsyncNetworkRequestFuncThatReturnsJSON()
                let newData = unpackJSONToDict(data)
                observer.sendNext(newData)
                observer.sendCompleted()
            }
            .flatMap(FlattenStrategy.Latest, transform: dataHandler)
    }

    func unpackJSONToDict(data: JSON) -> NSDictionary {
        /// deal with JSON data and return desired data as NSDictionary
    }

    func dataHandler(dict: NSDictionary) -> SignalProducer<NSDictionary, NSError> {
        /// do something with dict
    }

imagine a SignalProducer that creates a network request to http://www.timeapi.org/utc/now , parses the time string into a NSDate, and sends that NSDate on the produced Signal.

func getTimeSignal() -> SignalProducer<NSDate, NetworkError> {
  return SignalProducer { sink, disposable in
    let request = new Request("http://www.timeapi.org/utc/now")
    Client().performRequest(request) { result in
      switch result {
        case let .Failure(error):
          sink.sendFailed(error)
        case let .Success(timeString): 
          sink.sendNext(parseDate(timeString))
          sink.sendCompleted()
      }
    }
  }
}

Because the SignalProducer has side effects--in this case the network request, which will return different data when executed at different times, and could also fail randomly if the connection went down or the timeAPI server were to crash--the signals it produces when start() is called will see a different timeline of events!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM