Как я могу получить нужные мне данные из этого массива массивов? - PullRequest
0 голосов
/ 03 сентября 2018

Мне нужно проанализировать JSON из API, чтобы получить два массива данных, один для Times и один для цен.

Вот запрос:

func getReq(arr: Bool, completion: @escaping (Bool) -> ()){
    Dates.shared.formatDate()

    switch graphSetup {
    case .day:
        days = "1"
    case .week:
        days = "14"
    }

    let url = "https://api.coingecko.com/api/v3/coins/bitcoin/market_chart?vs_currency=usd&days=1"

    Alamofire.request(url).responseJSON { response in
        switch response.result {
        case .failure(let error):
            // Do whatever here
            return

        case .success(let data):
            // First make sure you got back a dictionary if that's what you expect
            let responseJSON = JSON(response.result.value!)
            if responseJSON.count != 0 {

                //do whatever you want with your object json

                parse(json: responseJSON)
                print(responseJSON)
                let gd = responseJSON["prices"].arrayValue

                completion(arr)
            }
        }
    }

Это именно то, что возвращает JSON (print (responseJSON) Я сократил его.

let json = "{
  "prices" : [
[
  1535841336422,
  7186.4600704446984
],
[
  1535841628453,
  7187.2085293179398
],
[
  1535841936398,
  7189.7057414152769
],
... many others ...,
[
  1535889024161,
  7210.4807839639352
],
[
  1535889339150,
  7211.0670314913395
 ]
]
}"

После разбора я получаю этот массив массивов. Как я могу отделить время от цен, сохраняя их в правильном порядке, чтобы я мог создать график с [Times] в качестве оси X и [Цены] в качестве Y?

Я думаю что-то вроде этого:

var times: [Int] = [] // Will probably convert to traditional date for chart
var prices: [Double] = []

Итак, я получаю:

print(times)
[1535837138223,1535837424517,1535837741575,...]
print(prices)
[5560.902754859002,5542.734892949798,5539.4334214537,...]

и теперь могу правильно настроить мой график. Как я могу это сделать? В качестве альтернативы, если есть лучший способ настроить данные моей диаграммы (я использую danielgindi / Charts для iOS), пожалуйста, дайте мне знать.

1 Ответ

0 голосов
/ 03 сентября 2018

Вам необходимо структурировать свои данные и создать собственный кодер / декодер для кодирования / декодирования массива различных типов данных UInt64 (время эпохи unix) и Double (цена):

struct Root: Codable {
    let prices: [Price]
}
struct Price: Codable {
    let date: Date
    let price: Double
}

extension Price {
    public init(from decoder: Decoder) throws {
        var unkeyedContainer = try decoder.unkeyedContainer()
        let date = try unkeyedContainer.decode(UInt64.self).date
        let price = try unkeyedContainer.decode(Double.self)
        self.init(date: date, price: price)
    }
    public func encode(to encoder: Encoder) throws {
        var unkeyedContainer = encoder.unkeyedContainer()
        try unkeyedContainer.encode(date.unixEpochTime)
        try unkeyedContainer.encode(price)
    }
}

extension UInt64 {
    var date: Date {
        return Date(timeIntervalSince1970: TimeInterval(self)/1000)
    }
}
extension Date {
    var unixEpochTime: UInt64 {
        return UInt64(timeIntervalSince1970*1000)
    }
}

Тестирование игровой площадки:

let json = """
{"prices": [[1535837138223,5560.902754859002],
            [1535837424517,5542.734892949798],
            [1535837741575,5539.4334214537]]}
"""

do {
    let prices = try JSONDecoder().decode(Root.self, from: Data(json.utf8)).prices
    print(prices.first!.date.description(with:.current))  // "Saturday, September 1, 2018 at 6:25:38 PM Brasilia Standard Time\n"
    print(prices.first!.price)  // "5560.902754859\n"

} catch {
    print(error)
}
...