Swift Json 使用不确定的传入数据解码
Swift Json decoding with unsure incoming data
我正在努力解码 swift 中的一些 Json 数据。
我的后端 api 会 return 我要么是一个 X 数组,要么是一个对象(至少)有一个 属性 名为 X 类型数组的“items”。
我搜索过但没有找到解决方案。你有吗?
struct A: Decodable {
var items: [X]
// some other optional properties
public init(from decoder: Decoder) throws {
// Sometimes I receive the correct A object
// Sometimes I only receive the array of X without the surrounding object of type A.
}
}
更糟糕的是,我必须解码,就像我总是收到类型 A 的对象一样...:[=16=]
myObjectOfTypeA = try decoder.decode(A.self, from: data)
大多数时候,我会收到像这样的合适的 A 对象:
{
"items":
[
{
"id": 7,
"startsOn": "2021-03-01",
"endsOn": "2021-12-31"
},
{
"id": 6,
"startsOn": "2021-04-19",
"endsOn": "2022-04-04"
}
],
"next": null,
"prev": null,
"count": 2
}
但有时,我只会收到这样的项目数组:
[
{
"id": 7,
"startsOn": "2021-03-01",
"endsOn": "2021-12-31"
},
{
"id": 6,
"startsOn": "2021-04-19",
"endsOn": "2022-04-04"
}
]
任何想法将不胜感激,因为我自己显然没有想法...
您只需要尝试解码您的封闭类型项并捕获错误。如果是类型不匹配错误,请尝试再次解码。无需创建自定义解码器:
struct A: Decodable {
let items: [X]
}
struct X: Decodable {
let id: Int
let startsOn: Date
let endsOn: Date
}
游乐场测试:
let json = """
{
"items":
[
{
"id": 7,
"startsOn": "2021-03-01",
"endsOn": "2021-12-31"
},
{
"id": 6,
"startsOn": "2021-04-19",
"endsOn": "2022-04-04"
}
],
"next": null,
"prev": null,
"count": 2
}
"""
let dateFormatter = DateFormatter()
dateFormatter.calendar = .init(identifier: .iso8601)
dateFormatter.locale = .init(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd"
let jsonDecoder = JSONDecoder()
jsonDecoder.dateDecodingStrategy = .formatted(dateFormatter)
let items: [X]
do {
items = try jsonDecoder.decode(A.self, from: Data(json.utf8)).items
} catch DecodingError.typeMismatch {
items = try jsonDecoder.decode([X].self, from: Data(json.utf8))
} catch {
items = []
print(error)
}
print(items)
它将为两个 json 输入打印以下内容:
[X(id: 7, startsOn: 2021-03-01 03:00:00 +0000, endsOn: 2021-12-31 03:00:00 +0000), X(id: 6, startsOn: 2021-04-19 03:00:00 +0000, endsOn: 2022-04-04 03:00:00 +0000)]
我正在努力解码 swift 中的一些 Json 数据。
我的后端 api 会 return 我要么是一个 X 数组,要么是一个对象(至少)有一个 属性 名为 X 类型数组的“items”。
我搜索过但没有找到解决方案。你有吗?
struct A: Decodable {
var items: [X]
// some other optional properties
public init(from decoder: Decoder) throws {
// Sometimes I receive the correct A object
// Sometimes I only receive the array of X without the surrounding object of type A.
}
}
更糟糕的是,我必须解码,就像我总是收到类型 A 的对象一样...:[=16=]
myObjectOfTypeA = try decoder.decode(A.self, from: data)
大多数时候,我会收到像这样的合适的 A 对象:
{
"items":
[
{
"id": 7,
"startsOn": "2021-03-01",
"endsOn": "2021-12-31"
},
{
"id": 6,
"startsOn": "2021-04-19",
"endsOn": "2022-04-04"
}
],
"next": null,
"prev": null,
"count": 2
}
但有时,我只会收到这样的项目数组:
[
{
"id": 7,
"startsOn": "2021-03-01",
"endsOn": "2021-12-31"
},
{
"id": 6,
"startsOn": "2021-04-19",
"endsOn": "2022-04-04"
}
]
任何想法将不胜感激,因为我自己显然没有想法...
您只需要尝试解码您的封闭类型项并捕获错误。如果是类型不匹配错误,请尝试再次解码。无需创建自定义解码器:
struct A: Decodable {
let items: [X]
}
struct X: Decodable {
let id: Int
let startsOn: Date
let endsOn: Date
}
游乐场测试:
let json = """
{
"items":
[
{
"id": 7,
"startsOn": "2021-03-01",
"endsOn": "2021-12-31"
},
{
"id": 6,
"startsOn": "2021-04-19",
"endsOn": "2022-04-04"
}
],
"next": null,
"prev": null,
"count": 2
}
"""
let dateFormatter = DateFormatter()
dateFormatter.calendar = .init(identifier: .iso8601)
dateFormatter.locale = .init(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd"
let jsonDecoder = JSONDecoder()
jsonDecoder.dateDecodingStrategy = .formatted(dateFormatter)
let items: [X]
do {
items = try jsonDecoder.decode(A.self, from: Data(json.utf8)).items
} catch DecodingError.typeMismatch {
items = try jsonDecoder.decode([X].self, from: Data(json.utf8))
} catch {
items = []
print(error)
}
print(items)
它将为两个 json 输入打印以下内容:
[X(id: 7, startsOn: 2021-03-01 03:00:00 +0000, endsOn: 2021-12-31 03:00:00 +0000), X(id: 6, startsOn: 2021-04-19 03:00:00 +0000, endsOn: 2022-04-04 03:00:00 +0000)]