Coinbase API 解析为 Swift App returns 格式不正确

Coinbase API parsing into Swift App returns incorrect formatting

我正在使用 coinmarketcap api 使用下面的代码获取硬币价格。在代码以及 JSON 响应之后,数据模型 Coin 也在下面给出。我收到错误消息“无法读取数据,因为它的格式不正确。”正确的格式应该是什么样的?

'''

import Foundation
import SwiftUI
import Alamofire

class CryptoViewModel: ObservableObject {
    
    func fetchData() {
        let headers: HTTPHeaders = [
            "Accepts": "application/json",
              "X-CMC_PRO_API_KEY": "5dd693fc-6446-44c4-8aaa-75b1bfa4376f"
        ]
        
        AF.request("https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest", headers: headers).response { response in
            guard let data = response.data else { return }
            
            do {
                let coins = try JSONDecoder().decode([Coin].self, from: data)
                print(coins)
            }
            catch {
                print(error.localizedDescription)
            }
            
        }
        
    }
    
}

'''

'''

import SwiftUI

struct Coin: Decodable {
    
    var slug: String?
    var symbol: String?
    
    enum CodingKeys: String, CodingKey {
        case slug = "slug"
        case symbol = "symbol"
    }
}

'''

'''

success({
    data =     (
                {
            "circulating_supply" = 18697137;
            "cmc_rank" = 1;
            "date_added" = "2013-04-28T00:00:00.000Z";
            id = 1;
            "last_updated" = "2021-05-02T14:22:02.000Z";
            "max_supply" = 21000000;
            name = Bitcoin;
            "num_market_pairs" = 9549;
            platform = "<null>";
            quote =             {
                USD =                 {
                    "last_updated" = "2021-05-02T14:22:02.000Z";
                    "market_cap" = "1063000586851.752";
                    "percent_change_1h" = "0.09591311";
                    "percent_change_24h" = "-1.05109813";
                    "percent_change_30d" = "-4.45794679";
                    "percent_change_60d" = "11.80459387";
                    "percent_change_7d" = "14.06195861";
                    "percent_change_90d" = "69.54985569999999";
                    price = "56853.65555441735";
                    "volume_24h" = "40969975368.50657";
                };
            };
            slug = bitcoin;
            symbol = BTC;
            tags =             (
                mineable,
                pow,
                "sha-256",
                "store-of-value",
                "state-channels",
                "coinbase-ventures-portfolio",
                "three-arrows-capital-portfolio",
                "polychain-capital-portfolio",
                "binance-labs-portfolio",
                "arrington-xrp-capital",
                "blockchain-capital-portfolio",
                "boostvc-portfolio",
                "cms-holdings-portfolio",
                "dcg-portfolio",
                "dragonfly-capital-portfolio",
                "electric-capital-portfolio",
                "fabric-ventures-portfolio",
                "framework-ventures",
                "galaxy-digital-portfolio",
                "huobi-capital",
                "alameda-research-portfolio",
                "a16z-portfolio",
                "1confirmation-portfolio",
                "winklevoss-capital",
                "usv-portfolio",
                "placeholder-ventures-portfolio",
                "pantera-capital-portfolio",
                "multicoin-capital-portfolio",
                "paradigm-xzy-screener"
            );
            "total_supply" = 18697137;
        }, ...

'''

首先,我认为您可能想删除示例中的 API 键并重新设置它。

关于你的问题。您的回复以 data 属性 开头。要解析它,您还需要在那里启动结构。

所以像这样的东西应该有用;

struct Coins: Decodable {
    let data: [Coin]

    struct Coin: Decodable {
        let symbol: String
        let slug: String
        let quote: [String: Quote]
    }

    struct Quote: Decodable {
        let price: Double
    }
}

我正在嵌套结构以保留命名空间。一切都非常相关。如果您需要单独访问其中之一,您可以将它们拉出来。

您也可以省略 CodingKeys,因为该键与您的变量名相同。另外我认为你在那里不需要选项,但我并不完全熟悉 API.

此外,我认为您只能返回一组数据,而不是一组硬币。所以我会在这里做以下事情;

let coins = try JSONDecoder().decode(Coins.self, from: data)

您正在将整个响应解析为硬币数组,但您感兴趣的实际数据位于 data 键下,因此您需要添加一个附加层

struct Coins: Decodable {
    let coins: [Coin]
}

并解码它而不是 Coin

let coins = try JSONDecoder().decode(Coins.self, from: data)