Swift访问字典中的数组值



我是来自Obj C背景的Swift的新手。我很难访问字典中的几个键值对,这些键值对来自API端点返回的一些JSON。我可以走到";数据";但不确定如何访问该键下的数组。具体地,我试图返回"0"的值;id";以及";价格;如下所示:

id = 1;
price = "20160.67609688202"

如果你能提供任何帮助,我将不胜感激。非常感谢。

Swift:

@IBAction func buttonAction(_ sender: Any) {


// Create the URL
let query = txt_Symbol.text
let api = "https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?CMC_PRO_API_KEY=myKey&symbol="
let endpoint = query!
let url = URL(string: api + endpoint)


guard let requestUrl = url else { fatalError() }
// Create URL Request
var request = URLRequest(url: requestUrl)
// Specify HTTP Method to use
request.httpMethod = "GET"
// Send HTTP Request
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in

// Check if Error took place
if let error = error {
print("Error took place (error)")
return
}

// Read HTTP Response Status code
if let response = response as? HTTPURLResponse {
print("Response HTTP Status code: (response.statusCode)")
}

// Convert HTTP Response Data to a simple String
if let data = data, let dataString = String(data: data, encoding: .utf8) {
print("Response data string:n (dataString)")



do {
if let convertedJsonIntoDict = try JSONSerialization.jsonObject(with: data, options: []) as? NSDictionary {
// Print out entire dictionary
print("convertedJsonIntoDict:")
print(convertedJsonIntoDict)


// UI API called on a background thread
// Call this on the main thread
DispatchQueue.main.async {
//Do UI Code here.

self.txtarea_JSON.text = convertedJsonIntoDict.description


// Get a value by key
let coinData = convertedJsonIntoDict["data"]
print(coinData ?? "coin could not be read")
                        
// how do I access these key value pairs?    
// id = 1;
// price = "20160.67609688202"
                         

}


}
} catch let error as NSError {
print(error.localizedDescription)
}




}

}
task.resume()
}

JSON:

{
data =     {
BTC =         {
"circulating_supply" = 19138912;
"cmc_rank" = 1;
"date_added" = "2013-04-28T00:00:00.000Z";
id = 1;
"is_active" = 1;
"is_fiat" = 0;
"last_updated" = "2022-09-02T03:39:00.000Z";
"max_supply" = 21000000;
name = Bitcoin;
"num_market_pairs" = 9718;
platform = "<null>";
quote =             {
USD =                 {
"fully_diluted_market_cap" = "423374198034.52";
"last_updated" = "2022-09-02T03:39:00.000Z";
"market_cap" = "385853405678.7285";
"market_cap_dominance" = "39.0616";
"percent_change_1h" = "0.83296442";
"percent_change_24h" = "0.16774456";
"percent_change_30d" = "-11.73989491";
"percent_change_60d" = "5.58985077";
"percent_change_7d" = "-6.59123025";
"percent_change_90d" = "-31.87091684";
price = "20160.67609688202";
tvl = "<null>";
"volume_24h" = "29753736862.94145";
"volume_change_24h" = "-7.2446";
};
};
"self_reported_circulating_supply" = "<null>";
"self_reported_market_cap" = "<null>";
slug = bitcoin;
symbol = BTC;
tags =             (
mineable,
pow,
"sha-256",
"store-of-value",
"state-channel",
"coinbase-ventures-portfolio",
"three-arrows-capital-portfolio",
"polychain-capital-portfolio",
"binance-labs-portfolio",
"blockchain-capital-portfolio",
"boostvc-portfolio",
"cms-holdings-portfolio",
"dcg-portfolio",
"dragonfly-capital-portfolio",
"electric-capital-portfolio",
"fabric-ventures-portfolio",
"framework-ventures-portfolio",
"galaxy-digital-portfolio",
"huobi-capital-portfolio",
"alameda-research-portfolio",
"a16z-portfolio",
"1confirmation-portfolio",
"winklevoss-capital-portfolio",
"usv-portfolio",
"placeholder-ventures-portfolio",
"pantera-capital-portfolio",
"multicoin-capital-portfolio",
"paradigm-portfolio"
);
"total_supply" = 19138912;
"tvl_ratio" = "<null>";
};
};
status =     {
"credit_count" = 1;
elapsed = 35;
"error_code" = 0;
"error_message" = "<null>";
notice = "<null>";
timestamp = "2022-09-02T03:41:38.218Z";
};

}

您可以将api响应解码为一组模型(结构(,而不是字典。

下面是一个示例代码,展示了如何解码api响应并使用它。(您需要根据服务器文档调整型号(

一旦将数据解码到模型中,它就比嵌套(键、值(对的字典更容易处理。

let formatter: DateFormatter = {
let frmt = DateFormatter()
frmt.dateFormat =  "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
return frmt
}()
if let data = data {
do {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(formatter)
let decoded = try decoder.decode(APIResponse.self, from: data)
// print("n---> decoded: n (decoded)")

if let coinData = decoded.data.first?.value {
print("n---> coinData: n (coinData)")
print("n---> coinData name: n (coinData.name)")
print("n---> coinData quote: n (coinData.quote)")
print("n---> coinData quote usd: n (coinData.quote.usd)")
}
} catch {
print("==> decoding error: (error)")
}
}

模型声明如下:

struct APIResponse: Codable {
let data: [String : CoinData]
let status: Status
}
struct CoinData: Identifiable, Codable {
let id: Int
let name, symbol, slug: String
let isActive, isFiat, circulatingSupply, totalSupply: Int
let maxSupply: Int
let dateAdded: Date
let numMarketPairs, cmcRank: Int
let lastUpdated: Date
let tags: [String]
let platform, selfReportedCirculatingSupply, selfReportedMarketCap: String?
let quote: Quote

enum CodingKeys: String, CodingKey {
case id, name, symbol, slug
case isActive = "is_active"
case isFiat = "is_fiat"
case circulatingSupply = "circulating_supply"
case totalSupply = "total_supply"
case maxSupply = "max_supply"
case dateAdded = "date_added"
case numMarketPairs = "num_market_pairs"
case cmcRank = "cmc_rank"
case lastUpdated = "last_updated"
case tags, platform
case selfReportedCirculatingSupply = "self_reported_circulating_supply"
case selfReportedMarketCap = "self_reported_market_cap"
case quote
}
}
struct Quote: Codable {
let usd: Usd

enum CodingKeys: String, CodingKey {
case usd = "USD"
}
}
struct Usd: Codable {
let price, volume24H, volumeChange24H, percentChange1H: Double
let percentChange24H, percentChange7D, percentChange30D, marketCap: Double
let marketCapDominance: Int
let fullyDilutedMarketCap: Double
let lastUpdated: Date

enum CodingKeys: String, CodingKey {
case price
case volume24H = "volume_24h"
case volumeChange24H = "volume_change_24h"
case percentChange1H = "percent_change_1h"
case percentChange24H = "percent_change_24h"
case percentChange7D = "percent_change_7d"
case percentChange30D = "percent_change_30d"
case marketCap = "market_cap"
case marketCapDominance = "market_cap_dominance"
case fullyDilutedMarketCap = "fully_diluted_market_cap"
case lastUpdated = "last_updated"
}
}
struct Status: Codable {
let timestamp: Date
let errorCode: Int
let errorMessage: String
let elapsed, creditCount: Int

enum CodingKeys: String, CodingKey {
case timestamp
case errorCode = "error_code"
case errorMessage = "error_message"
case elapsed
case creditCount = "credit_count"
}
}

根据您在问题中显示的JSON响应,以下是从中获取值的方法:

do {
guard let response = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
print("JSONSerialization Not possible")
return
}

guard let data = response["data"] as? [String: Any] else { return }
guard let btc = data["BTC"] as? [String: Any] else { return }
guard let quote = btc["quote"] as? [String: Any], let usd = quote["USD"] as? [String: Any] else { return }

let id = btc["id"] as? Int ?? 0
let price = usd["price"] as? String ?? ""

print(id)       //1
print(price)    //20160.67609688202

} catch let error {
print(error.localizedDescription)
}

最新更新