我无法使用 swift 进行 MVVM 设计项目时提取 Json 数据



我正在Swift中制作一个MVVM设计项目。我想从加密网站获得硬币名称,当前价格,等级和符号。我无法在控制台上显示我获得的json数据。模型在另一个文件夹中,因为我是用MVVM做的。如何创建结构以在此处获取数据?你可以在下面找到我项目的截图。如果你帮忙,我会很高兴的。

以下是我在我的网络服务文件中写的代码

import Foundation
class WebService {

func downloadCurrencies(url: URL, completion: @escaping ([DataInfo]?) -> ()) {

URLSession.shared.dataTask(with: url) { (data, response, error) in

if let error = error {
print(error.localizedDescription)
completion(nil)

} else if let data = data {

let cryptoList = try? JSONDecoder().decode([DataInfo].self, from: data)

print(cryptoList)

if let cryptoList = cryptoList {
completion(cryptoList)
}
}

}
.resume()
}
}

以下是我在模型文件中写的代码

import Foundation
struct DataInfo : Decodable {

var name: String
var symbol: String
var cmc_rank: String
var usd: Double

}

最后,这是我为将viewController中的数据打印到控制台而编写的代码。但不幸的是,我无法提取数据。

override func viewDidLoad() {
super.viewDidLoad()

let url = URL(string: "https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?start=1&limit=10&convert=USD&CMC_PRO_API_KEY=5ac24b80-27a1-4d01-81bd-f19620533480")!

WebService().downloadCurrencies(url: url) { cryptos in
if let cryptos = cryptos {
print(cryptos)
}
}
}

我看到了你的URL,并在Postman上对其进行了测试,我也得到了你的代码,并试图将其格式化,代码很好,但它无法将JSON数据映射到你的结构中,因为这是Postman的JSON数据邮差数据

当查看您的结构时,它与您接收的JSON数据的格式不匹配,

结构

好吧,为了使您的结构与JSON字符串匹配,您需要创建嵌套的String: Any字典。但逻辑还有另一个问题,您需要解码webservice调用之外的数据,因为它可能包含无法映射到结构中的错误,并且如果您获得其他状态代码,则可以处理这些错误。

如果您尝试手动实现所有这些内容,代码将变得复杂且难以理解。我建议您将Alamofire与SwiftyJSON一起使用,它可以使您的工作变得更短、更容易、更易于理解。

抱歉英语不好。

您的api密钥对我无效。您的数据必须在对象或无效键中,并且您肯定会丢失它,这就是它无法正确解析的原因。

我的建议是把你的json响应放在这个网站

"https://app.quicktype.io/">

用新的结构替换你的结构,你就可以满怀希望地去了。

您的模型与响应对象没有1到1的对应关系。根对象不是[DataInfo],而是包含DataInfos数组的另一个结构。以下是正确的模型

struct Response: Codable {
let status: Status
let data: [CurrencyData]
}
struct Status: Codable {
let creditCount: Int
let elapsed: Int
let timestamp: String
let totalCount: Int
let errorCode: Int?
let errorMessage: String?
let notice: String?
enum CodingKeys: String, CodingKey {
case notice
case timestamp
case elapsed
case creditCount = "credit_count"
case errorCode = "error_code"
case errorMessage = "error_message"
case totalCount = "total_count"
}
}
enum Currency: String, Codable, Hashable {
case usd = "USD"
}
struct CurrencyData: Codable {
let circulatingSupply: Double?
let cmcRank: Int
let dateAdded: String?
let id: Int
let lastUpdated: String?
let maxSupply: Int?
let name: String
let numMarketPairs: Int
let platform: Platform?
let quote: [String: Price]
let selfReportedCirculatingSupply: String?
let selfReportedMarketCap: String?
let slug: String
let symbol: String
let tags: [String]?
let totalSupply: Double

func price(for currency: Currency) -> Double? {
return quote[currency.rawValue]?.price
}
enum CodingKeys: String, CodingKey {
case id
case name
case platform
case quote
case slug
case symbol
case tags
case circulatingSupply = "circulating_supply"
case cmcRank = "cmc_rank"
case dateAdded = "date_added"
case lastUpdated = "last_updated"
case maxSupply = "max_supply"
case selfReportedCirculatingSupply = "self_reported_circulating_supply"
case selfReportedMarketCap = "self_reported_market_cap"
case totalSupply = "total_supply"
case numMarketPairs = "num_market_pairs"
}
}
struct Price: Codable {
let fullyDilutedMarketCap: Double?
let lastUpdated: String?
let marketCap: Double?
let marketCapDominance: Double?
let percentChange1h: Double?
let percentChange24h: Double?
let percentChange30d: Double?
let percentChange60d: Double?
let percentChange7d: Double?
let percentChange90d: Double?
let price: Double?
let volume24h: Double?
let volumeChange24h: Double?
enum CodingKeys: String, CodingKey {
case price
case fullyDilutedMarketCap = "fully_diluted_market_cap"
case lastUpdated = "last_updated"
case marketCap = "market_cap"
case marketCapDominance = "market_cap_dominance"
case percentChange1h = "percent_change_1h"
case percentChange24h = "percent_change_24h"
case percentChange30d = "percent_change_30d"
case percentChange60d = "percent_change_60d"
case percentChange7d = "percent_change_7d"
case percentChange90d = "percent_change_90d"
case volume24h = "volume_24h"
case volumeChange24h = "volume_change_24h"
}
}
struct Platform: Codable {
let id: Int
let name: String
let symbol: String
let slug: String
let tokenAddress: String?

enum CodingKeys: String, CodingKey {
case id
case name
case symbol
case slug
case tokenAddress = "token_address"
}
}

您可以在完成处理程序中检索cryptoList,如下所示:

let cryptoList = (try? JSONDecoder().decode([Response].self, from: data))?.data

此外,将您的个人数据暴露在互联网上(API_KEY等(也是不安全的。

最新更新