Многоадресная рассылка в ReactiveCocoa 3 и ReactiveCocoa 4
Допустим, у меня есть функция, которая возвращает SignalProducer<AnyObject?, NSError>
и я хочу связать производителя с несколькими MutableProperty<String>
, Итак, как то так:
let foo = SignalProducer<AnyObject?, NSError>(value: nil)
let someProperty1 = MutableProperty<String>("")
let someProperty2 = MutableProperty<String>("")
someProperty1 <~ foo
.flatMapError { _ in
SignalProducer<AnyObject?, NoError>.empty
}
.map { _ in
return "test"
}
// someProperty2 <~ foo etc...
Чтобы избежать многократного запуска моей функции (например, некоторых сетевых вещей), мне нужно использовать многоадресную рассылку. Насколько я могу судить из CHANGELOG, startWithSignal
оператор для этого. Однако я не могу понять, как это сделать декларативно.
Таким образом, один из подходов мог бы заключаться в том, чтобы сделать обязательным startWithSignal
:
foo.startWithSignal { signal, disposable in
someProperty1 <~ signal
.map { _ in
return "test"
}
// someProperty2 <~ signal etc...
}
Однако это, очевидно, потерпит неудачу, потому что мы должны избавиться от NSError
часть. Потому что мы даем Signal
(в отличие от SignalProducer
), мы не можем использовать flatMapError
(в RAC4, catch
в RAC3). И я не вижу, как mapError
может сделать это для нас? Наконец, я даже не уверен, что это правильный способ обработки многоадресной рассылки в RAC3/RAC4?
Буду признателен за любую оказанную помощь.
2 ответа
Использование flatMapError
(и любые другие операторы, которые должны принять SignalProducer
аргумент) до starWithSignal
let fooIgnoreError = foo
.flatMapError { _ in
SignalProducer<AnyObject?, NoError>.empty
}
fooIgnoreError.startWithSignal { signal, disposable in
someProperty1 <~ signal.map { _ in "test" }
someProperty2 <~ signal.map { _ in "test2" }
}
Если fooIgnoreError
запускается только один раз, ваш основной источник сигнала foo
гарантированно будет запущен только один раз.
Я объяснил, как реализовать многоадресную рассылку на примере здесь.
Что касается ошибок, вы можете сделать свою собственность AnyProperty<Result<Value, Error>>
уметь пересылать ошибки. Если вы хотите, чтобы сигнал прекратился при сбое, вы можете просто
signal.flatMapError { error in
fatalError("Error: \(error)") // or some other form of error handling, or simply ignoring the error?
return .empty
}