I'm pretty new to ReactiveCocoa 3 and Swift and have the following code example. I'd like to map the signal returned from the map
function to receive the JSON
values in the start
function at the end.
At the moment I'm passing through a Signal<JSON, NSError>
which I observe
inside the start
function. Is there a better solution to this?
import Foundation
import ReactiveCocoa
import SwiftyJSON
class SearchViewModel {
let results = MutableProperty<[MyModel]>([])
let searchText = MutableProperty<String>("")
init() {
searchText.producer
|> map { keyword -> Signal<JSON, NSError> in Api().get("search/\(keyword)") }
|> start(
next: { signal in
signal
|> observe(
next: { jsonArray in
let models = jsonArray.arrayValue.map(modelAdapter)
self.results.put(models)
}
)
}
)
}
}
It turned out the problem was my understanding of ReactiveCocoa. See my answer below.
It turned out my Api.get()
function should return a SignalProducer
instead of a Signal
. With this adjustment I ended up with a solution like this:
let keywordToJson: SignalProducer<String, NSError> -> SignalProducer<JSON, NSError> = flatMap(.Concat) { keyword in Api().get("search/\(keyword)" }
searchText.producer
|> mapError { _ in NSError() }
|> keywordToJson
|> start(
next: { jsonArray in
let models = jsonArray.arrayValue.map(modelAdapter)
self.results.put(models)
}
)
Notes:
(1) At the moment it seems to be necessary that you have to give the compiler some hints about the type of the flatMap
function.
(2) You also need to remap the error of your properties producer
from NoError
to NSError
.