JSONDecoder 无法处理空响应
JSONDecoder can't handle null response
上下文
我正在使用 Firebase Database REST API 和 JSONDecoder / JSONEncoder。到目前为止,它一直运行良好。
然而,对于 removing data,预期的返回响应是 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: "The given data was not valid JSON.",
underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840
"JSON text did not start with array or object and option to allow
fragments not set." UserInfo={NSDebugDescription=JSON text did not
start with array or object and option to allow fragments not set.}))))
我尝试创建自定义类型 (NoReply
) 来按照 a previous post 处理此问题,但没有成功。
代码
这是错误发生的地方:
resource: {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
return try decoder.decode(Resource.self, from: [=11=])
},
error: {
let decoder = JSONDecoder()
return try decoder.decode(FirebaseError.self, from: [=11=])
}
所以很明显,即使我提供自定义 NoReply 类型(根据上面提到的 post)JSONDecoder 也不喜欢 null
.
有什么建议吗?
作为旁注,这是他们的文档中关于 DELETE 操作响应的内容:
A successful DELETE request is indicated by a 200 OK HTTP status code
with a response containing JSON null
.
不幸的是,JSONDecoder
没有公开支持 JSON 片段的基础 JSONSerialization
选项(.allowFragments
),如单独的 null
值。您可以尝试转换响应或直接使用 JSONSerialization
。不幸的是,这里没有什么优雅的事情可以做。
快速跟进
经过几次成功的破解,我想出的最优雅的解决方案是组合:
- 使用
NoReply
(as described by 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: [=11=])
},
其中资源 none 除了 :
public struct NoReply: Decodable {}
现在效果很好,让我可以处理不存在的对象上的 DELETE 和 GET 情况 returns null
.
感谢您的帮助!
上下文
我正在使用 Firebase Database REST API 和 JSONDecoder / JSONEncoder。到目前为止,它一直运行良好。
然而,对于 removing data,预期的返回响应是 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: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}))))
我尝试创建自定义类型 (NoReply
) 来按照 a previous post 处理此问题,但没有成功。
代码
这是错误发生的地方:
resource: {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
return try decoder.decode(Resource.self, from: [=11=])
},
error: {
let decoder = JSONDecoder()
return try decoder.decode(FirebaseError.self, from: [=11=])
}
所以很明显,即使我提供自定义 NoReply 类型(根据上面提到的 post)JSONDecoder 也不喜欢 null
.
有什么建议吗?
作为旁注,这是他们的文档中关于 DELETE 操作响应的内容:
A successful DELETE request is indicated by a 200 OK HTTP status code with a response containing JSON
null
.
不幸的是,JSONDecoder
没有公开支持 JSON 片段的基础 JSONSerialization
选项(.allowFragments
),如单独的 null
值。您可以尝试转换响应或直接使用 JSONSerialization
。不幸的是,这里没有什么优雅的事情可以做。
快速跟进
经过几次成功的破解,我想出的最优雅的解决方案是组合:
- 使用
NoReply
(as described by 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: [=11=]) },
其中资源 none 除了 :
public struct NoReply: Decodable {}
现在效果很好,让我可以处理不存在的对象上的 DELETE 和 GET 情况 returns null
.
感谢您的帮助!