我想使用 JSONDecoder
解码 JSON。它按预期工作,但对于内部对象为空的 JSON,JSONDecoder
会抛出错误由于缺少数据而无法读取数据。
错误时的 JSON 示例:
{
"header": {
"code": 1053,
"message": "Incorrect information."
},
"body": {}
}
成功时的 JSON 示例:
{
"header": {
"code": 1053
"message": "Nice information."
},
"body": {
"client_id": 12345
}
}
成功的JSON,很容易解码。但在 Error JSON 上,它抛出错误。
这是我正在使用的代码
struct ApiResponse: Decodable {
let header: Header
let body: Body
struct Header: Decodable {
let responseCode: Int
let message: String
}
struct Body: Decodable {
let clientId: Int
}
}
let decoder: JSONDecoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let decodedResponse = try decoder.decode(ApiResponse.self, from: data)
最佳答案
您可以扩展KeyedDecodingContainer
,以使用协议(protocol)将空字典视为nil
public protocol EmptyDictionaryRepresentable {
associatedtype CodingKeys : RawRepresentable where CodingKeys.RawValue == String
associatedtype CodingKeyType: CodingKey = Self.CodingKeys
}
extension KeyedDecodingContainer {
public func decodeIfPresent<T>(_ type: T.Type, forKey key: KeyedDecodingContainer.Key) throws -> T?
where T : Decodable & EmptyDictionaryRepresentable
{
guard contains(key) else { return nil }
let container = try nestedContainer(keyedBy: type.CodingKeyType.self, forKey: key)
return container.allKeys.isEmpty ? nil : try decode(T.self, forKey: key)
}
}
要使用它,请采用协议(protocol)并将受影响的属性声明为可选
struct ApiResponse: Decodable {
let header: Header
let body: Body?
}
struct Body: Decodable, EmptyDictionaryRepresentable {
enum CodingKeys : String, CodingKey { case clientId = "client_id" }
let clientId: Int
}
警告:此解决方案不适用于 .convertFromSnakeCase
策略
注意:考虑 Header
中的键 - 结构成员名称不匹配
关于ios - 使用 JSONDecoder 解码带有空对象的 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60061276/