如何使用CombineAnyPublisher处理空的json主体?

问题描述

给出我负责处理正文的发布者。比我可以解码为User结构。效果很好。

// 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{ $0.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{ $0.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 { $0.response as? HTTPURLResponse }
    .receive(on: DispatchQueue.main)
    .eraseToAnyPublisher()

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

如果只需要状态码,则可以在.map(\.statusCode)之后调用compactMap-或将compactMap的主体更改为($0 as? HTTPURLResponse).statusCode,这将导致输出类型为Int而不是HTTPURLResponse的发布商。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...