如何在ReactiveSwift中撰写动作("从此列表中运行第一个启用的动作")

时间:2017-05-10 09:50:54

标签: swift reactive-swift

我有两个Action s具有相同的输入/输出/错误类型,我想将它们组合成一个Action来运行两个中的任何一个(使用如果他们两个都是一个任意的决胜局。)

这是我的第一次失败尝试:

let addOrRemove: Action<MyInput, MyOutput, APIRequestError> = Action(enabledIf: add.isEnabled.or(remove.isEnabled)) { input in
    if add.isEnabled.value {
        return add.apply(input)
    } else {
        return remove.apply(input)
    }
}

这会失败,因为内部add.apply(input)无法看到我检查add.isEnabled,因此它会在错误类型周围包含一个额外的ActionError<>图层。 (这可能是合法的,因为我不确定这种方法的线程安全性如何,或者可能是我们知道类型系统没有的事情。)相应的类型错误是:

cannot convert return expression of type 'SignalProducer<MyOutput, ActionError<APIRequestError>>' to return type 'SignalProducer<MyOutput, APIRequestError>'

我该怎么办?

1 个答案:

答案 0 :(得分:1)

Github用户@ikesyoReactiveSwift issue I opened to ask the same question上提供了以下答案:

let producer: SignalProducer<MyOutput, ActionError<APIRequestError>>
if add.isEnabled.value {
    producer = add.apply(input)
} else {
    producer = remove.apply(input)
}
return producer.flatMapError { error in
    switch error {
    case .disabled: return .empty
    case let .producerFailed(inner): return SignalProducer(error: inner)
    }
}

如果他们出现在这里,我会很乐意改变他们接受的答案(信用证所在的地方)。

警告:如果我正确地阅读了这个答案,那么它不是水密的。如果add在包裹apply()的{​​{1}}和start()之间从启用更改为禁用,我们将获得成功&#34; (没有值,但是Action)而不是我们应该得到的.completed。这对我的用例来说已经足够了,但YMMV。