簡體   English   中英

如何使用手動解碼編寫枚舉

[英]how to write enum with manual decoding

我有一個 json 響應,它是這樣的:

"Details": {
        "Attachments": [],
        "place": {
          "destination": {
            "type": "international",
            "Id": "superman",
            "locationType": "City",
            "Name": "Kent"
          },
          "package": 52.32,
          "description": "Dinner"
        }
      }
    }

在此響應中,目標中的所有參數都是可選的,但類型除外,因此我將像這樣處理此響應:

public struct Destination: Decodable, Equatable {
    public let Id: String?
    public let Name: String?
    public let city: String?
    public let locationType: String?
    public let pinCode: String?
    public let country: String?
    public let state: String?
    public let currency: String?
    public let language: String?
    public let type: Type
}

由於所有參數都是可選的,並且基於類型,我將只獲得這些參數中的幾個作為響應。 喜歡 -

type: "international",
       country: "US"
       id: "5",
       currency: "Dollar"

有什么辦法可以在枚舉中寫這個:

enum Destination {
case international(country: String, id: String, currency: String)
case national(state: String, language: String, pincode: String)
}

誰能回答我應該如何開始使用這種方法。謝謝

由於 Swift 5.5 具有關聯值的枚舉具有Codable 合成,但這需要頂級容器包含與枚舉大小寫名稱匹配的單個鍵。 在您的情況下,您在容器中使用什么值來確定大小寫,因此唯一的解決方案是自己編寫init(from decoder: Decoder) ,解碼所有關聯的值,然后返回枚舉值。

這樣的事情會起作用:

public struct Place: Decodable {
    var destination: Destination
}

enum Destination: Decodable {
    case international(country: String?, Id: String?, currency: String?)
    case national(state: String?, language: String?, pincode: String?)

    enum CodingKeys: String, CodingKey {
        case type
        case country
        case Id
        case currency
    }

    init(from decoder: Decoder) throws {
        var container = try decoder.container(keyedBy: CodingKeys.self)
        let type = try container.decode(String.self, forKey: .type)
        let country = try container.decodeIfPresent(String.self, forKey: .country)
        let Id = try container.decodeIfPresent(String.self, forKey: .Id)
        let currency = try container.decodeIfPresent(String.self, forKey: .currency)

        switch type {
        case "international":
            self = Destination.international(country: country, Id: Id, currency: currency)
        case "national":
            fatalError("not supported yet")
            () // similary
        default:
            fatalError("not supported yet")
            () // throw an decoding error
        }
    }
}

以上適用於您提供的 JSON:

let json = """ {
        "destination": {
            "type": "international",
            "Id": "superman",
            "country": "City",
            "currency": "Kent"
        } } """ 

    do {
         let data = try JSONDecoder().decode(Place.self, from: json.data(using: .utf8)!) 
   } 
   catch {
         print("error \(error)") 
   }

你必須寫枚舉如

Enum CodingKeys: String, CodingKey {

    case Id, Name, city, locationType, pinCode, country, state, currency, language = String?

    case type = Type
}
struct Details: Decodable {

  enum CodingKeys: String, CodingKey {
      case Attachments, place
  }

  let Attachments: Array?
    let place: Place?

}

struct Place: Decodable {
  let destination: Destination?
    let package: Double?
    let description: String?
}

struct Destination: Decodable {
  let type, Id, locationType, Name: String?
}

暫無
暫無

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

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