我如何使用 Combine (AnyPublisher) 处理空的 json 正文?

How could I handle empty json body with Combine (AnyPublisher)?

考虑到这个发布者,我在其中处理正文响应。比我可以解码为用户结构。效果很好。

// Wrapped Request, return with an URLRequest object with POST method
let request = RequestWithModel(networkMethod: .post, path: PathBuilder().user().build(), model: User(userId: 1, title: "fokora", body: "baroka")).urlRequest()

let addUser : AnyPublisher<User, Error> = URLSession.shared.dataTaskPublisher(for: request)
.map{ [=11=].data }
.decode(type: User.self, decoder: JSONDecoder())
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()

当响应为空 json 正文时如何处理响应,但我想知道它是否成功(状态代码为 200)?我需要使用什么样的发布者?

// Wrapped Request, return with an URLRequest object with DELETE method
let request = RequestWithoutModel(networkMethod: .delete, path: PathBuilder().user().id(id: "1").build()).urlRequest()
let deleteUser : AnyPublisher<... no need this ..., Error> = URLSession.shared.dataTaskPublisher(for: request)
.map{ [=12=].data }
.decode(type: ... no need this ..., decoder: JSONDecoder()) // no need to decode anything at all
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()

提前感谢您提供的任何帮助。

如果您只关心响应,则应该 map response 属性 而不是 data。如果您还想检查响应代码,您应该将 response 转换为 HTTPURLResponse

let deleteUser = URLSession.shared.dataTaskPublisher(for: request)
    .compactMap { [=10=].response as? HTTPURLResponse }
    .receive(on: DispatchQueue.main)
    .eraseToAnyPublisher()

这将导致类型为 AnyPublisher<HTTPURLResponse, URLSession.DataTaskPublisher.Failure> 的发布者。

如果你只需要状态码,你可以在compactMap之后调用.map(\.statusCode)——或者将compactMap的主体改为([=20=] as? HTTPURLResponse).statusCode,这将导致在输出类型为 Int 而不是 HTTPURLResponse.

的发布者中