Swift Codable with Different Array Types

后端 未结 1 1957
感情败类
感情败类 2021-01-13 08:03

I\'m writing a program where I\'m parsing JSON data that includes array of arrays, where the nested arrays have different object types (specifically, [[String,

相关标签:
1条回答
  • 2021-01-13 08:17

    One solution (assuming you can't change the JSON) is to implement custom decoding logic for Bet. You can use an unkeyed container (which reads from a JSON array) in order to decode each of the properties in turn (the order in which you call decode(_:) is the order they're expected to appear in the array).

    import Foundation
    
    struct OrderBook : Codable {
      let number: Int
      let bets: [Bet]
    }
    
    struct Bet : Codable {
      let price: String
      let sale: String
      let quantity: Int
    
      init(from decoder: Decoder) throws {
        var container = try decoder.unkeyedContainer()
        self.price = try container.decode(String.self)
        self.sale = try container.decode(String.self)
        self.quantity = try container.decode(Int.self)
      } 
    
      // if you need encoding (if not, make Bet Decodable
      // and remove this method)
      func encode(to encoder: Encoder) throws {
        var container = encoder.unkeyedContainer()
        try container.encode(price)
        try container.encode(sale)
        try container.encode(quantity)
      }
    }
    

    Example decoding:

    let jsonString = """
    { "number": 5295, "bets": [["16","83",9], ["75","99",4], ["46","27",5]] }
    """
    
    let jsonData = Data(jsonString.utf8)
    
    do {
      let decoded = try JSONDecoder().decode(OrderBook.self, from: jsonData)
      print(decoded)
    } catch {
      print(error)
    }
    
    // OrderBook(number: 5295, bets: [
    //   Bet(price: "16", sale: "83", quantity: 9),
    //   Bet(price: "75", sale: "99", quantity: 4),
    //   Bet(price: "46", sale: "27", quantity: 5)
    // ])
    
    0 讨论(0)
提交回复
热议问题