簡體   English   中英

Swift 可使用不同的字典類型數組進行編碼

[英]Swift Codable with Different Array of Dictionary Types

我有 JSON 數據,它是一個字典數組,其中第一項與數組項的 rest 不同。

樣品 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))
   }
 }

我嘗試過的事情

  1. 我通過我的網絡請求將“DashboardSummary”結構作為可編碼傳遞,它確實為第一項提供了結果,當然也為數組的 rest 提供了 nil 值。

  2. 我嘗試了 init(來自解碼器:解碼器)func 編碼(到編碼器:編碼器) ,不幸的是這對我不起作用。

我怎樣才能解決這個問題?

首先,您需要創建第三個可以表示數組的結構,例如:

struct Response : Codable {
    var dashboardSummary: DashboardSummary?
    var daySummaries: [DaySummary]
    
    enum CodingKeys: CodingKey {
        case dashboardSummary, daySummaries
    }
}

然后你需要實現init(from:)encode(to:)來進行自定義編碼。

您可以使用unkeyedContainer進行解碼/編碼。 解碼時, 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)
    }
}

如果您不打算更改屬性,也可以考慮將屬性設置為常量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM