如何从该阵列数组中获取所需的数据?

时间:2018-09-02 21:43:29

标签: ios arrays json swift charts

我需要从API解析JSON,以获取两个数据数组,一个用于Times,一个用于Price。

这是请求:

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
 ]
]
}"

解析后,我得到了这个数组数组。如何在将价格与时间分开的同时保持正确的顺序,以便创建以[时间]为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,...]

,现在可以正确设置我的图表了。我怎样才能做到这一点?另外,如果有更好的方法来设置图表数据(我在使用iOS的danielgindi / Charts),请告诉我。

1 个答案:

答案 0 :(得分:1)

您需要构建数据并创建自定义编码器/解码器,以对不同数据类型的数组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)
}