I want to use Alamofire to query my backend, encode the response using Alamofire's built-in Codable parsing and then publish an extract from the resulting Struct to be consumed by the caller of my API class. Say I have some JSON data from my backend (simplified, but shows the structure):
{
"total": 123,
"results": [
{"foo" : "bar"},
{"foo" : "baz"}
]
}
and the associated Codable
Structs
struct MyServerData: Codable {
let total: Int
let results: [Result]
}
struct Result: Codable {
let foo: String
}
I can get, parse, publish, and subscribe all fine with the following:
func myAPI() -> DataResponsePublisher<MyServerData> {
return AF.request("https://backend/path")
.validate()
.publishDecodable(type: MyServerData.self)
}
myAPI()
.sink { response in /* Do stuff, e.g. update @State */ }
What I'd like to do is to publish just the [Result]
array. What's the correct approach to this? Should I use .responseDecodable()
and create a new publisher (somehow - .map()
?) that returns a [Result].publisher
?
While I think I understand the reactive/stream based principles my Combine-fu is still weak and I don't have a clear handle on the transformation of one publisher into another (I'm guessing?)
Thanks in advance!
CodePudding user response:
In addition to using Combine API like map
, Alamofire offers two publishers on DataResponsePublisher
itself.
.result()
extracts the Result
from the DataResponse
and creates an AnyPublisher<Result<Value, AFError>, Never>
.
.value()
extracts the Value
from the DataResponse
and creates a failable publisher, AnyPublisher<Value, AFError>
.
So depending on what kind of error handling you want, this could be as simple as:
...
.publishDecodable(...)
.value()
.map(\.results)