Многоадресная рассылка в 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
}
Другие вопросы по тегам