Swift 可使用不同的字典类型数组编码
Swift Codable with Different Array of Dictionary Types
我有JSON个数据,它是一个字典数组,其中第一项与其余数组项不同。
样本JSON
[
{
"totalDays": 180,
"totalWorkingDays": 148,
"totalWorkingHours": "1184:00:00",
"totalWorkedHours": "985:23:10",
"totalShortageHours": "-199:37:50",
"avgWorkingHours": "06:39:28(83%)",
"avgShortageHours": "01:20:31(17%)",
"totalAbsents": 13,
"totalLeaves": 4
},
{
"attendanceDayCount": 1,
"attendanceDate": "21-Jan-19",
"attendanceDay": "Monday"
},
{
"attendanceDayCount": 2,
"attendanceDate": "22-Jan-19",
"attendanceDay": "Tuesday"
},
{
"attendanceDayCount": 3,
"attendanceDate": "23-Jan-19",
"attendanceDay": "Wednesday"
}
]
我正在使用 Codable,我的结构如下所示
struct DashboardSummary : Codable {
var totalDays : Int?
var totalWorkingDays : Int?
var totalWorkingHours : String?
var totalWorkedHours : String?
var totalShortageHours : String?
var avgWorkingHours : String?
var avgShortageHours : String?
var totalAbsents : Int?
var totalLeaves : Int?
}
struct DaySummary : Codable {
var attendanceDayCount : Int?
var attendanceDate : String?
var attendanceDay : String?
}
编辑:JSON 从网络请求方法解码
DispatchQueue.main.async {
if let responseObject = try? JSONDecoder().decode(Response.self, from: data) {
print("responseObject", responseObject)
completion(.success(responseObject))
}
else {
let error = NSError(domain: "", code: 200, userInfo: [NSLocalizedDescriptionKey : "Failed to decode"])
completion(.failure(error))
}
}
我试过的东西
我通过我的网络请求将 'DashboardSummary' 结构传递为可编码,它确实给出了第一项的结果,当然数组的其余部分为零值。
我尝试了 init(from decoder: Decoder) 和 func encode(to encoder: Encoder) 不幸的是对我不起作用。
我该如何解决这个问题?
首先,你需要创建一个third结构体来表示数组,例如:
struct Response : Codable {
var dashboardSummary: DashboardSummary?
var daySummaries: [DaySummary]
enum CodingKeys: CodingKey {
case dashboardSummary, daySummaries
}
}
然后您需要实施 init(from:)
和 encode(to:)
来进行自定义编码。
您可以使用 unkeyedContainer
到 decode/encode 它。解码的时候,你一直从容器while
解码,容器不是isAtEnd
.
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
dashboardSummary = try container.decodeIfPresent(DashboardSummary.self)
daySummaries = []
while !container.isAtEnd {
daySummaries.append(try container.decode(DaySummary.self))
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(dashboardSummary)
for daySummary in daySummaries {
try container.encode(daySummary)
}
}
如果您不打算更改这些属性,也可以考虑将其设置为常量。
我有JSON个数据,它是一个字典数组,其中第一项与其余数组项不同。
样本JSON
[
{
"totalDays": 180,
"totalWorkingDays": 148,
"totalWorkingHours": "1184:00:00",
"totalWorkedHours": "985:23:10",
"totalShortageHours": "-199:37:50",
"avgWorkingHours": "06:39:28(83%)",
"avgShortageHours": "01:20:31(17%)",
"totalAbsents": 13,
"totalLeaves": 4
},
{
"attendanceDayCount": 1,
"attendanceDate": "21-Jan-19",
"attendanceDay": "Monday"
},
{
"attendanceDayCount": 2,
"attendanceDate": "22-Jan-19",
"attendanceDay": "Tuesday"
},
{
"attendanceDayCount": 3,
"attendanceDate": "23-Jan-19",
"attendanceDay": "Wednesday"
}
]
我正在使用 Codable,我的结构如下所示
struct DashboardSummary : Codable {
var totalDays : Int?
var totalWorkingDays : Int?
var totalWorkingHours : String?
var totalWorkedHours : String?
var totalShortageHours : String?
var avgWorkingHours : String?
var avgShortageHours : String?
var totalAbsents : Int?
var totalLeaves : Int?
}
struct DaySummary : Codable {
var attendanceDayCount : Int?
var attendanceDate : String?
var attendanceDay : String?
}
编辑:JSON 从网络请求方法解码
DispatchQueue.main.async {
if let responseObject = try? JSONDecoder().decode(Response.self, from: data) {
print("responseObject", responseObject)
completion(.success(responseObject))
}
else {
let error = NSError(domain: "", code: 200, userInfo: [NSLocalizedDescriptionKey : "Failed to decode"])
completion(.failure(error))
}
}
我试过的东西
我通过我的网络请求将 'DashboardSummary' 结构传递为可编码,它确实给出了第一项的结果,当然数组的其余部分为零值。
我尝试了 init(from decoder: Decoder) 和 func encode(to encoder: Encoder) 不幸的是对我不起作用。
我该如何解决这个问题?
首先,你需要创建一个third结构体来表示数组,例如:
struct Response : Codable {
var dashboardSummary: DashboardSummary?
var daySummaries: [DaySummary]
enum CodingKeys: CodingKey {
case dashboardSummary, daySummaries
}
}
然后您需要实施 init(from:)
和 encode(to:)
来进行自定义编码。
您可以使用 unkeyedContainer
到 decode/encode 它。解码的时候,你一直从容器while
解码,容器不是isAtEnd
.
init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
dashboardSummary = try container.decodeIfPresent(DashboardSummary.self)
daySummaries = []
while !container.isAtEnd {
daySummaries.append(try container.decode(DaySummary.self))
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(dashboardSummary)
for daySummary in daySummaries {
try container.encode(daySummary)
}
}
如果您不打算更改这些属性,也可以考虑将其设置为常量。