如何解析一个JSON数据块而不是整个JSON序列

时间:2019-06-19 14:07:24

标签: json swift decodable

以下是用于解析JSON API的代码。该代码有效,我能够将所有JSON值解析为以下结构,但我想知道如何仅解析第一个block(?)/数组并将其存储在该结构中,以便对它们执行操作。

     let jsonUrlString = "https://www.alphavantage.co/query?function=FX_INTRADAY&from_symbol=EUR&to_symbol=USD&interval=5min&apikey=demo"

        let urlObj = URL(string: jsonUrlString)

        URLSession.shared.dataTask(with: urlObj!) {(data, response, error) in
            guard let data = data else { return }
            do {
                let forex = try JSONDecoder().decode(Root.self, from: data)
                print(forex.timeSeriesFX5Min)
            } catch {

                print(error)
            }

            }.resume()
    }
}

struct Root: Codable {
    let timeSeriesFX5Min: [String:Forex]

    enum CodingKeys: String, CodingKey {
        case timeSeriesFX5Min = "Time Series FX (5min)"
    }
}


    // MARK: - TimeSeriesFX5Min
    struct Forex: Codable {
        let the1Open, the2High, the3Low, the4Close: String

        enum CodingKeys: String, CodingKey {
            case the1Open = "1. open"
            case the2High = "2. high"
            case the3Low = "3. low"
            case the4Close = "4. close"
        }

    }

2 个答案:

答案 0 :(得分:0)

发出请求时,您可能会通过回调正确通知谁用您的请求值调用您的方法? 因此,您将创建对象或数组对象的新实例并填充结果。

如果要在此结构中创建,则只需获取arrayObject并使用.first并遵循此逻辑...

示例:

var newRoot: [Root] = [] 
func loadRoot() {
    Service().makeRequest() { (result, error) int
         newRoot = result.results
         print(newRoot.first)
    }
}

函数“ makeRequest()”将调用您编写的方法。

let jsonUrlString = "https://www.alphavantage.co/query?function=FX_INTRADAY&from_symbol=EUR&to_symbol=USD&interval=5min&apikey=demo"

    let urlObj = URL(string: jsonUrlString)

    URLSession.shared.dataTask(with: urlObj!) {(data, response, error) in
        guard let data = data else { return }
        do {
            let forex = try JSONDecoder().decode(Root.self, from: data)
            print(forex.timeSeriesFX5Min)
        } catch {

            print(error)
        }

        }.resume()
}
}

答案 1 :(得分:0)

我看到了两种方法,第一种方法是更改​​Root结构,我们需要在其中使用消息的元数据部分

do {
    let forex = try JSONDecoder().decode(Root.self, from: data)
    print(forex.metaData)
    if let latestTime = forex.metaData["4. Last Refreshed"], let latestForex = forex.timeSeriesFX5Min[latestTime] {
        print(latestForex)
    }        
} catch {
    print(error)
}

然后,我们选择标记为“最新报价”的项目,并使用该值在时间序列字典中查找最新的价格条目

if let latestTime = forex.timeSeriesFX5Min.keys.sorted().last, let latestForex = forex.timeSeriesFX5Min[latestTime] {
     print(latestForex)
}

另一种选择是利用以下事实:时间戳记以可以正确排序的格式给出,因此我们不使用元数据而是对键进行排序并选择最后一项

Dst_Port  Packet_leng Time Source_IP
53 80 03/10/2019 15:01:42 172.16.1.9
53 80 03/11/2019 15:01:42 172.16.1.9
138 258 03/12/2019 15:01:43 172.16.2.1
138 235 03/13/2019 15:01:43 172.16.2.1
57621 76 03/14/2019 15:01:43 172.16.1.9
57621 76 03/15/2019 15:03:29 157.7.235.92
57621 68 03/16/2019 15:05:33 172.16.0.1


(df.groupby(df.index.hour)['Packet_length']
   .agg({'Packet': ['min','max','mean', 'median', 'std']})
   .plot(kind='bar',title='Day - Hourly Packets', legend=True, ax=ax))