【问题标题】:struct for nested dictionary API in swiftswift中嵌套字典API的结构
【发布时间】:2018-10-26 03:06:35
【问题描述】:

我正在尝试从 coinmarketcap API v2 导入 JSON 数据。我让它与 v1 一起工作,因为它是一个数组,但是新版本是一个字典,我不能完全让我的结构正确。 我使用的 API 是:https://api.coinmarketcap.com/v2/ticker/?convert=AUD

我的结构设置如下:

struct Coin: Decodable {
private enum CodingKeys: String, CodingKey {
    case id = "rank", symbol, name, priceAUD = "quotes"
}
var id: String
var symbol : String
var name : String
var priceAUD : quoteStruct

}

struct quoteStruct{
    let aud : priceStruct
}

struct priceStruct{
    let price : String
}

我获取数据的代码是:

var coins = [Coin]()

func getCoinData() {
    let jsonURL = "https://api.coinmarketcap.com/v2/ticker/?convert=AUD"
    let url = URL(string: jsonURL)

    URLSession.shared.dataTask(with: url!) { [unowned self] (data, response, error) in
        guard let data = data else { return }
        do {
            self.coins = try JSONDecoder().decode([Coin].self, from: data)
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }

        } catch {
            print("Error is : \n\(error)")
        }
        }.resume()
}

我用于获取数据的代码与之前使用的 API 的 v1 相同,但是我认为我的结构不正确。

提前致谢!

【问题讨论】:

  • JSON 是字典,而不是数组。 “第一个”键是data,它根本不会出现在您的解析中。你期望它如何工作?因为[Coin].self 表示您将拥有Coin 的数组,但事实并非如此。您的结构不会模仿 JSON 结构。
  • 您的数据应该是array 而不是dictionary。如何在未定义的键上迭代字典?最好先更新您对 API 的响应。
  • 谢谢大家,我最好对字典的解析做更多研究

标签: ios json swift xcode api


【解决方案1】:

您的回复已更改,我尝试通过将其转换为字典数组来配置它,您需要将 quotes 更改为 [String:priceStruct]

struct Coin: Decodable {
    private enum CodingKeys: String, CodingKey {
        case id,rank,symbol, name, priceAUD = "quotes"
    }
    var id: Int
    var rank: Int
    var symbol : String
    var name : String
    var priceAUD : [String: priceStruct]

}

struct priceStruct : Decodable{
    let price : Double
}

 func getCoinData() {
         var coins = [Coin]()
        let jsonURL = "https://api.coinmarketcap.com/v2/ticker/?convert=AUD"
        let url = URL(string: jsonURL)

        URLSession.shared.dataTask(with: url!) { [unowned self] (data, response, error) in
            guard let data = data else { return }
            do {
                 if let json = try JSONSerialization.jsonObject(with: data) as? [String: Any], let resultData = json["data"]  as? [String:Any] {

                     let dataObject = try JSONSerialization.data(withJSONObject: resultData.values.map({$0})  , options: .prettyPrinted)
                    coins = try JSONDecoder().decode([Coin].self, from: dataObject)
                    print(coins.count)

                  }



            } catch {
                print("Error is : \n\(error)")
            }
            }.resume()
    }

【讨论】:

    【解决方案2】:

    您在data 参数中的响应应该是一个数组而不是字典。您将无法在未定义的键上迭代字典。最好先更新您对 API 的响应。

    但是,如果您希望继续使用现有的 API 响应,首先您需要将您的响应转换为数组并使用您的 Decodable 结构:

    struct Coin: Decodable {
        var id: String
        var symbol : String
        var name : String
        var priceAUD : QuoteStruct
    
        private enum CodingKeys: String, CodingKey {
            case id = "rank", symbol, name, priceAUD = "quotes"
        }
    }
    
    struct QuoteStruct: Decodable {
        let aud : PriceStruct
    }
    
    struct PriceStruct: Decodable {
        let price : String
    }
    

    将 API 块中的数据解析更新为:

        guard let responseData = data else { return }
        do {
            let json = try? JSONSerialization.jsonObject(with: responseData, options: [])
            if let jsonData = json as? [String: Any], let dataObject = jsonData["data"] as? [Int: Any] {
                let coinArray = dataObject.map { $0.1 }
    
                if let jsonData = try? JSONSerialization.data(withJSONObject: coinArray, options: .prettyPrinted) {
                    coins = try JSONDecoder().decode([Coin].self, from: jsonData)
                    DispatchQueue.main.async {
                        self.tableView.reloadData()
                    }
                }
            }
        } catch {
            print("Error is : \n\(error)")
        }
    

    【讨论】:

    • 非常感谢!这工作得很好,不需要我过度重组我的整个项目:)
    • 欢迎@SeanSlack。
    猜你喜欢
    • 2019-05-02
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-22
    • 1970-01-01
    • 2021-09-15
    • 1970-01-01
    相关资源
    最近更新 更多