Как преобразовать структуру JSON в словарь или структуру - PullRequest
0 голосов
/ 04 мая 2019

Я извлекаю обменные курсы для разных валют. У меня есть решение, которое работает, но оно не выглядит элегантным. Я использую входной файл JSON и хочу преобразовать его в словарь, чтобы можно было легко получить доступ к обменному курсу валюты за определенный день.

Моя цель - найти лучший способ сделать это без лишнего кода и гибкости.

Это в Swift 5, с входным файлом JSON. Входной файл выглядит так:

{
"terms":{
    "url": "https://www.banqueducanada.ca/conditions-utilisation-avis/"
},
"seriesDetail":{
"FXEURCAD":{"label":"EUR/CAD","description":"Taux de change quotidien de l’euro en dollars canadiens"},
"FXGBPCAD":{"label":"GBP/CAD","description":"Taux de change quotidien de la livre sterling en dollars canadiens"},
"FXMXNCAD":{"label":"MXN/CAD","description":"Taux de change quotidien du peso mexicain en dollars canadiens"},
"FXUSDCAD":{"label":"USD/CAD","description":"Taux de change quotidien du dollar américain en dollars canadiens"}
},
"observations":[
{"d":"2019-04-29","FXUSDCAD":{"v":1.3456}, "FXEURCAD":{"v":1.5029}, "FXGBPCAD":{"v":1.7391}, "FXMXNCAD":{"v":0.07083}},
{"d":"2019-04-30","FXUSDCAD":{"v":1.3423}, "FXEURCAD":{"v":1.5055}, "FXGBPCAD":{"v":1.7493}, "FXMXNCAD":{"v":0.07071}},
{"d":"2019-05-01","FXUSDCAD":{"v":1.3416}, "FXEURCAD":{"v":1.5070}, "FXGBPCAD":{"v":1.7540}, "FXMXNCAD":{"v":0.07105}},
{"d":"2019-05-02","FXUSDCAD":{"v":1.3462}, "FXEURCAD":{"v":1.5055}, "FXGBPCAD":{"v":1.7543}, "FXMXNCAD":{"v":0.07053}},
{"d":"2019-05-03","FXUSDCAD":{"v":1.3429}, "FXEURCAD":{"v":1.5021}, "FXGBPCAD":{"v":1.7611}, "FXMXNCAD":{"v":0.07069}}
]
}

Я извлекаю раздел "наблюдения".

Список валют на дату может отличаться. Это может иметь больше или меньше. У меня есть минимум одна валюта. Я хотел бы иметь решение, которое не требует, чтобы я вручную кодировал разные обменные курсы.

func getCurrencies (){
    var currencies = [String : [String:Double]]()

    if let urlJSON = URL(string: "https://www.banqueducanada.ca/valet/observations/FXUSDCAD,FXEURCAD,FXGBPCAD,FXMXNCAD/json?recent=5"){
        do {
            let contents =  try String(contentsOf: urlJSON)
            print(contents)

            let data = Data(contents.utf8)

            if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
               let observations = json["observations"] as! [[String: Any]]
                for (x,part) in observations.enumerated() {
                    let date = part["d"] as! String
                    currencies [date] = [String:Double]()

                    // get the currencies in the JSON structure

                    currencies [date]!["FXEURCAD"] = (part["FXEURCAD"] as! [String : Double])["v"]
                    currencies [date]!["FXGBPCAD"] = (part["FXGBPCAD"] as! [String : Double])["v"]
                    currencies [date]!["FXMXNCAD"] = (part["FXMXNCAD"] as! [String : Double])["v"]
                    currencies [date]!["FXUSDCAD"] = (part["FXUSDCAD"] as! [String : Double])["v"]
                } // for
                print (currencies)
            } // if  let json
        } catch {}
    } // if
} // getCurrencies

Произведен словарь валюты в порядке:

["2019-05-02": ["FXGBPCAD": 1.7543, "FXMXNCAD": 0.07053, "FXEURCAD": 1.5055, "FXUSDCAD": 1.3462], 
 "2019-05-01": ["FXGBPCAD": 1.754, "FXEURCAD": 1.507, "FXMXNCAD": 0.07105, "FXUSDCAD": 1.3416], 
 "2019-05-03": ["FXEURCAD": 1.5021, "FXUSDCAD": 1.3429, "FXMXNCAD": 0.07069, "FXGBPCAD": 1.7611], 
 "2019-04-30": ["FXEURCAD": 1.5055, "FXMXNCAD": 0.07071, "FXUSDCAD": 1.3423, "FXGBPCAD": 1.7493], 
 "2019-04-29": ["FXGBPCAD": 1.7391, "FXEURCAD": 1.5029, "FXUSDCAD": 1.3456, "FXMXNCAD": 0.07083]]

Я могу извлечь значение с помощью этой команды:

   print (currencies ["2019-05-03"]!["FXUSDCAD"]!)

Есть ли лучший способ сделать это? JSONSerialization.jsonObject правильный способ сделать это?

1 Ответ

0 голосов
/ 04 мая 2019

В этом случае JSONSerialization - разумный способ, однако никогда не загружайте данные синхронно с удаленного URL.

Это более общая версия с параметром для валют и с асинхронным сетевым запросом.

func getCurrencies(_ currencies : [String]){
    var result = [String : [String:Double]]()

    if let urlJSON = URL(string: "https://www.banqueducanada.ca/valet/observations/" + currencies.joined(separator:",") + "/json?recent=5"){
        URLSession.shared.dataTask(with: urlJSON) { (data, _, error) in
            if let error = error { print(error); return }
            do {
                if let json = try JSONSerialization.jsonObject(with: data!) as? [String: Any] {
                    let observations = json["observations"] as! [[String: Any]]
                    for part in observations {
                        let date = part["d"] as! String
                        result[date] = [String:Double]()

                        // get the currencies in the JSON structure
                        for currency in currencies {
                            result[date]![currency] = (part[currency] as! [String : Double])["v"]
                        }
                    } // for
                    print(result)
                } // if  let json
            } catch {
                print(error)
            }
        }.resume()
    } // if
} // getC


getCurrencies(["FXUSDCAD","FXEURCAD","FXGBPCAD","FXMXNCAD"])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...