JSONDecoder 无法处理空响应



上下文

我正在使用Firebase数据库REST API和JSONDecoder/JSONEncoder。到目前为止,它一直运行得很好。然而,对于删除数据,预期返回的响应是null,而JSONDecoder似乎不太喜欢这样。

这是我通过Postman发送的查询类型,以及我得到的信息(不包括敏感数据(。

DELETE /somedata/-LC03I3oHcLhQ/members/ZnWsJtrZ5UfFS6agajbL2hFlIfG2.json
content-type: application/json
cache-control: no-cache
postman-token: ab722e0e-98ed-aaaa-bbbb-123f64696123
user-agent: PostmanRuntime/7.2.0
accept: */*
host: someapp.firebaseio.com
accept-encoding: gzip, deflate
content-length: 39

HTTP/1.1 200
status: 200
server: nginx
date: Thu, 02 Aug 2018 21:53:27 GMT
content-type: application/json; charset=utf-8
content-length: 4
connection: keep-alive
access-control-allow-origin: *
cache-control: no-cache
strict-transport-security: max-age=31556926; includeSubDomains; preload
null

如您所见,响应代码为200,正文为null

错误

当我收到回复时,这就是我得到的错误:

Swift。DecodingError.dataCorrupted(Swift。DecodingError.Context(codingPath:[],debugDescription:"给定的数据不是有效的JSON。",underlyingError:可选(错误域=NSCocoaErrorDomain代码=3840"JSON文本未以数组或对象和选项开头碎片未设置。"UserInfo={NSDebugDescription=JSON文本没有从数组或对象和允许不设置片段的选项开始。}(((

我尝试创建一个自定义类型(NoReply(来处理这一问题,但没有成功。

代码

这就是错误发生的地方:

resource: {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
return try decoder.decode(Resource.self, from: $0)
},
error: {
let decoder = JSONDecoder()
return try decoder.decode(FirebaseError.self, from: $0)
}

所以很明显,即使我提供了一个自定义的NoReply类型(根据上面提到的帖子(,JSONDecoder也不喜欢null

有什么建议吗?


附带说明,这是他们的文档对DELETE操作的响应:

成功的DELETE请求由200 OK HTTP状态代码指示其中响应包含JSONnull

快速跟进

在几次成功的破解之后,我想出的最优雅的解决方案是:

  • 使用NoReply(如Zoul所述(
  • 将所述null字符串转换为空的JSON对象结构({}(

所以首先,转换:

if "null" == String(data: data, encoding: .utf8) {
let json = Data("{}".utf8)

然后将其反馈给处理请求响应的闭包:

resource: {
let decoder = JSONDecoder()
return try decoder.decode(Resource.self, from: $0)
},

其中资源正是:

公共结构NoReply:可解码{}

这现在工作得很好,允许我处理不存在对象上的DELETE情况和GET情况,它返回null

谢谢你的帮助!

不幸的是,JSONDecoder没有公开底层的JSONSerialization选项(.allowFragments(,该选项将支持JSON片段,如单独的null值。您可以尝试转换响应,或者直接使用JSONSerialization。不幸的是,这里没有什么高雅的事可做。

相关内容

  • 没有找到相关文章

最新更新