Reputation: 1928
I started using combine and it's really cool but currently I have no idea how to fix it. I want to make a POST Request using combine so I have to decode Data, create my request, send it and after that return an
AnyPublisher<Void, Error>
Currently my code looks like this:
func postData<T>(withURL urlRequest: URLRequest, object: T) -> AnyPublisher<Void, Error> where T: Encodable {
return Just(object)
.encode(encoder: JSONEncoder())
.mapError {
let error = self.classifyError($0)
return error
}
.map { data -> URLRequest in
var request = urlRequest
//BUILD REQUEST
return request
}
.flatMap { request in
let dataTaskPublisher: AnyPublisher<URLSession.DataTaskPublisher.Output, URLSession.DataTaskPublisher.Failure> = URLSession.DataTaskPublisher(request: request, session: .shared)
return dataTaskPublisher
.tryMap { try self.throwErrorOrContinue(data: $0, basedOnResponse: $1) }
.decode(type: T.self, decoder: JSONDecoder())
.mapError { return self.handle(error: $0, from: urlRequest, object: T.self) }
}
.eraseToAnyPublisher()
}
And he tells me:
Cannot convert return expression of type 'AnyPublisher<Publishers.FlatMap<_, Publishers.Map<Publishers.MapError<Publishers.Encode<Just<T>, JSONEncoder>, _>, URLRequest>>.Output, Publishers.FlatMap<_, Publishers.Map<Publishers.MapError<Publishers.Encode<Just<T>, JSONEncoder>, _>, URLRequest>>.Failure>' (aka 'AnyPublisher<_.Output, _>')
to return type 'AnyPublisher<Void, Error>'
I tried some mapping but it didn't work and I have no idea what he wants from me. Maybe one of you knows the problem? Thanks :)
Upvotes: 1
Views: 10807
Reputation: 271355
You could always map
to Void
, which is an empty tuple:
return URLSession.DataTaskPublisher(request: request, session: .shared)
.tryMap { try self.throwErrorOrContinue(data: $0, basedOnResponse: $1) }
.decode(type: T.self, decoder: JSONDecoder())
.mapError { return self.handle(error: $0, from: urlRequest, object: T.self) }
.map { _ in return () }
Also T
should be constrained to Decodable
.
But really though, I think postData
should return AnyPublisher<T, Error>
. What to do with the data got from the server should be decided by the caller of postData
. Therefore, you should change the return type of postData
instead. For example, if the caller wants to ignore the result, it could do:
Publishers.IgnoreOutput(upstream: postData(...))
This creates a Publisher
with Never
, rather than Void
, as its Output
. The publisher will only produce errors.
Upvotes: 2