我开始使用combine,它真的很酷,但目前我不知道如何修复它。我想使用combing发出POST请求,所以我必须解码数据,创建请求,发送它,然后返回
AnyPublisher<Void, Error>
目前我的代码如下:
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()
}
他告诉我:
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>'
我试着做了一些映射,但没有成功,我不知道他想从我这里得到什么。也许你们中的一个人知道问题所在?谢谢:(
您可以始终从map
到Void
,这是一个空元组:
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 () }
此外,T
应当被约束为Decodable
。
但实际上,我认为postData
应该返回AnyPublisher<T, Error>
。如何处理从服务器获得的数据应由postData
的调用方决定。因此,您应该更改postData
的返回类型。例如,如果调用者想忽略结果,它可以这样做:
Publishers.IgnoreOutput(upstream: postData(...))
这将创建一个Publisher
,其中Never
而不是Void
作为其Output
。发布者只会产生错误。