Migrate from RACSignal to ReactiveSwift or RAC5

白昼怎懂夜的黑 提交于 2019-12-10 21:05:20

问题


I'm new with Swift, and that's why I'm new with Reactive Cocoa v5 or Reactive Swift.

Previously I used RACSignal with RAC 2.x and I liked to do something like this:

- (RACSignal *)signalForGET:(NSString *)URLString parameters:(NSDictionary *)parameters {
  return [RACSignal createSignal:^RACDisposable *(id <RACSubscriber> subscriber) {
      AFHTTPRequestOperation *op = [self GET:URLString parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
          [subscriber sendNext:responseObject];
          [subscriber sendCompleted];
      } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
          [subscriber sendError:error];
      }];
      return [RACDisposable disposableWithBlock:^{
          [op cancel];
      }];
   }];
}

And here I loved that it cancels request on disposable, and also I could cancel it manually by calling dispose method on the returned signal.

I'm a little bit confused about all this stuff in Reactive Swift, like SignalProducers etc.

Please give me example how to implement the same with newest Swift/ReactiveSwift/ReactiveCocoa versions. Main requirement is to have ability to cancel request (or dispose signal) wherever I want, and to have request automatically getting cancelled on dispose


回答1:


The important thing to understand about Signal and SignalProducer is the distinction between Hot and Cold Signals.

Basically, a Hot Signal is one that does not care about its Observers. It sends its values, no matter if it has one, multiple or even no observer at all. And most important: New observations do not cause side effects in the signal and each new subscriber will get the exact same events as the other subscribers (minus the ones that have already occurred before the subscription!)! Think things like user input, sensor data, ... (ignoring things like starting/stopping the sensor).

In my experience, real Hot Signals are rare in practice..

In contrast, a Cold Signal is one that cares about its Observers - each subscription to a Cold Signal potentially performs a side effect and the subscriber receives events based on that side effect. So two different observers each start the side effect once and get distinct sets of events.

In RAC, Cold Signals are represented by SignalProducer. You might also think of a SignalProducer as a Factory for Signals (hence the name) - starting a SignalProducer performs the side effect and returns a Signal on which the events are sent.

Thats pretty much what your snippet does.

Disposable has not changed much since RAC 2.x, you can still use that. You probably have just missed how to use it when creating a SignalProducer:

func producerForGET(urlString: String, parameters: [String: String]) -> SignalProducer<Data, NSError> {
    return SignalProducer<Data, NSError> { observer, disposable in
        let operation = GET(url: urlString, parameters: parameters, success: { operation, responseObject in
            observer.send(value: responseObject)
            observer.sendCompleted()
        }, failure: { error in
            observer.send(error: error)
        })

        disposable += {
            print("Disposed")
            operation.cancel()
        }
    }
}

Here's a quick example how to use this can be used:

producerForGET(urlString: "Bla", parameters: [:])
    .start()    // Performs the request and returns a Signal
    .dispose()  // Runs the disposable block and cancels the operation


来源:https://stackoverflow.com/questions/43476727/migrate-from-racsignal-to-reactiveswift-or-rac5

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