4

I have been told by a bunch of people that codable is much better than using swiftyjson so I am trying it out. I want to convert the return from this JSON, https://api.gdax.com/products/BTC-USD/book?level=2 into two arrays (one for ask, one of bids). I also want the value of the sequnce in a seperate variable. This is how I am doing it using swiftyjson. How would this be done using codable? I am using alamofire for this.

This is the Alamofire call but it is pretty straightforward and irrelevant.

Alamofire.request(url, method: .get).responseJSON {(response) in
    switch response.result{
    case .success(let value):

Here is the important code:

let swiftyJson = JSON(value)

guard let sequenceNum = Int(swiftyJson["sequence"].stringValue) else {return}

let askOrders = swiftyJson["asks"].arrayValue
let bidOrders = swiftyJson["bids"].arrayValue

let askSideBook = askOrders.map({ (obj) -> (price:Double, size:Double, numOrders:Double) in
    let orderArray = obj.arrayValue

    let price = orderArray[0].doubleValue
    let size = orderArray[1].doubleValue
    let numOrders = orderArray[2].doubleValue

    return (price:price, size:size, numOrders:numOrders)
})

let bidSideBook = bidOrders.map({ (obj) -> (price:Double, size:Double, numOrders:Double) in
    let orderArray = obj.arrayValue

    let price = orderArray[0].doubleValue
    let size = orderArray[1].doubleValue
    let numOrders = orderArray[2].doubleValue

    return (price:price, size:size, numOrders:numOrders)
})

Here is the JSON shortened but it will give you the idea of the general format. As you can see the first value is the price, the second is the size, and the third is the number of orders. The price and size are both returned as a strings but I need them as a double.

{
  "sequence": 4448910440,
  "bids": [
    [
      "9679.96",
      "9.52707734",
      38
    ],
    [
      "9679.94",
      "0.12631007",
      3
    ],...
  ],
  "asks": [
    [
      "9679.97",
      "45.51632996",
      10
    ],
    [
      "9679.98",
      "1.31689466",
      1
    ],...
  ]
}

I have also heard of https://github.com/Otbivnoe/CodableAlamofire. Is this something that is recommended?

Here is what I have so far but I don't know how to work with the array by the index for each item in the ask and bid array.

struct OrderBookItems: Codable {
    let bidOrderBook: [DataPoints]
    let askOrderBook: [DataPoints]
    private enum CodingKeys: String, CodingKey {
        case bidOrderBook = "bid"
        case askOrderBook = "ask"
    }
}

1 Answer 1

1

The values for the codingKeys are wrong (plural form) and you need a second struct providing a custom initializer to decode the array

struct OrderBookItems: Decodable {
    let bidOrderBook: [DataPoint]
    let askOrderBook: [DataPoint]
    private enum CodingKeys: String, CodingKey {
        case bidOrderBook = "bids"
        case askOrderBook = "asks"
    }
}

struct DataPoint : Decodable {
    let price : Double
    let size : Double
    let numOrders : Int

    init(from decoder: Decoder) throws {
        var container = try decoder.unkeyedContainer()
        price = Double(try container.decode(String.self)) ?? 0.0
        size = Double(try container.decode(String.self)) ?? 0.0
        numOrders = try container.decode(Int.self)
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.