'I can't pull Json data while doing MVVM design project with swift
I am making a project in Swift with MVVM design. I want to get coin name, current price, Rank and Symbol from a Crypto site. I can't show the json data I get on the console. The model is in another folder because I did it with MVVM. How can I create a struct to get the data here? You can find screenshots of my project below. I would be glad if you help.
Below are the codes I wrote in my web service file
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()
}
}
Below are the codes I wrote in my model file
import Foundation
struct DataInfo : Decodable {
var name: String
var symbol: String
var cmc_rank: String
var usd: Double
}
Finally, here is the code I wrote to print the data in the viewController to my console. But unfortunately I can't pull the data.
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)
}
}
}
Solution 1:[1]
I've seen your URL and tested it ON Postman and also i've got your code and tried to put it in a shape, the code is good, but it can't MAP JSON Data against your struct because this is the json Data from Postman Postman Data
While Looking at your Struct, It Doesnt Match the format of JSON Data you're receiving,
Well, To Make your structure match the JSON String you need to create Nested String: Any
Dictionary. But there's another issue with the logic, you need to decode data outside of the webservice call because it can contain errors which wont be mapped in the struct and can handle if you get other statusCode.
If you try to implement all these things manually, the code will become complex and hard to understand. I would rather recommend you to use Alamofire with SwiftyJSON and it can make your work a lot shorter and easier and understandable.
Sorry for the bad english.
Solution 2:[2]
Your api-key is not valid for me. Your data must be inside of object or invalid keys and you are surely missing it thats why it is not parsing correctly.
My suggestion is to put your json response in this website
"https://app.quicktype.io/"
and replace your struct with new one, you will be good to go hopefully.
Solution 3:[3]
Your models are incorrect, try these
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"
}
}
Also it's not safe to expose your personal data to the internet (API_KEY, etc.)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Hashim Khan |
Solution 2 | DevIOS |
Solution 3 | narek.sv |