Search code examples
iosswiftreactive-cocoafrpalamofire

flattenMap and error handling in ReactiveCocoa with swift


After reading the following tutorial http://www.scottlogic.com/blog/2014/07/24/mvvm-reactivecocoa-swift.html I am trying to use ReactiveCocoa with Swift with in of my apps. When button is pressed I am making a request to check if server is responding:

_checkButton.rac_signalForControlEvents(UIControlEvents.TouchUpInside)
.flattenMap({(text: AnyObject!) -> RACStream! in
  return RACSignal.createSignal({ (subscriber: RACSubscriber!) -> RACDisposable! in
    Alamofire.request(.GET, "http://google.com")
    .validate(statusCode: 200..<300)
    .response{ (_, _, _, error) in
      if(error == nil) {
        subscriber.sendNext(true)
        subscriber.sendCompleted()
      } else {
        subscriber.sendError(error)
      }
    })
}).subscribeNextAs({ (value: AnyObject) -> () in
  println("success")
}, error: { (error: NSError) -> () in
  println("error")
}, completed: {})

When sendError() is called in flattenMap the signal is no more emmited when I am pressing the button. It works correctly as long as I am emitting sendNext() and sendCompleted() only.

Any clue on how to resolve this will be appreciated.


Solution

  • The sendError is causing the signal to terminate. From the ReactiveCocoa Design Guidelines:

    In RAC, error events have exception semantics. When an error is sent on a signal, it will be immediately forwarded to all dependent signals, causing the entire chain to terminate.

    If you want to sendError from your created RACSignal you'll need to use something like the -catch: operator to handle it downstream (before the subscribeNext) so it doesn't terminate the signal.