JSONDecoder无法处理空响应

时间:2018-08-02 22:32:52

标签: json swift firebase firebase-realtime-database decodable

上下文

我正在使用Firebase Database REST API和JSONDecoder / JSONEncoder。到目前为止,它一直运行良好。 但是,对于removing data,预期返回的响应是null,并且JSONDecoder似乎不太喜欢。

这是我通过邮递员发送的查询类型以及我得到的查询(不包括敏感数据)。

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。”,   底层错误:可选(错误域= NSCocoaErrorDomain代码= 3840   “ JSON文本不以数组或对象开头,并且允许   片段未设置。“ UserInfo = {NSDebugDescription = JSON文本未设置   从数组或对象开始,并选择允许不设置片段。}))))

我尝试创建自定义类型(NoReply)来按照a previous post进行处理,但无济于事。

代码

这是发生错误的地方:

        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状态代码指示   包含JSON null的响应。

2 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:3)

快速跟进

经过几次成功的黑客攻击后,我想到的最优雅的解决方案是组合:

  • 使用NoReply(如Zoul所述)
  • php artisan storage:link字符串转换为空的JSON对象结构(null

那么首先,转换:

{}

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

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

其中资源就是:

  

公共结构NoReply:可解码{}

这现在很好用,可以让我处理不存在的对象的DELETE和GET情况,该对象返回 resource: { let decoder = JSONDecoder() return try decoder.decode(Resource.self, from: $0) },

感谢您的帮助!