The fetch doesn't throw any error, it just returns nil, I don't know why, this is the api URL:
https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd&include_market_cap=true&include_24hr_vol=true&include_24hr_change=true&include_last_updated_at=true
Note: There is an infinite amount of tokens, not only Bitcoin, so I can't hardcode it.
it looks like:
{
"bitcoin": {
"usd": 51110,
"usd_market_cap": 964544028181.903,
"usd_24h_vol": 19080677597.123028,
"usd_24h_change": 2.163373654971005,
"last_updated_at": 1640575480
},
thereCanBeMoreWhichIcan'tPredict: {
...
}
}
This is the model I created:
struct TokenSimplePriceCoingeckoUsdModel: Codable, Hashable {
let usd, usd_market_cap, usd_24h_vol, usd_24h_change: Double?
let last_updated_at: Int?
}
and this is how I'm fetching it with Alamofire:
func afRequest(url: URL) async throws -> Data {
try await withUnsafeThrowingContinuation { continuation in
// If another error try lowering the request error: (statusCode: 200..<300)
// timeoutInterval is in seconds
AF.request(url, method: .get, requestModifier: { $0.timeoutInterval = .infinity }).validate(statusCode: 200..<600).responseData { response in
if let data = response.data {
continuation.resume(returning: data)
return
}
if case let .failure(error) = response.result {
print("🛑 Error on afRequest(): \(error)")
continuation.resume(throwing: error)
return
}
}
}
}
func getDataFromAPI(url: String) async -> Any {
do {
let url = URL(string: url)!
let undecodedData = try await afRequest(url: url)
let finalData = try JSONDecoder().decode(TokenSimplePriceCoingeckoUsdModel.self, from: undecodedData)
return finalData
} catch(let error) {
print("🛑 Error on getDataFromAPI(): ", error)
}
return ""
}
When I print the return of that I get:
TokenSimplePriceCoingeckoUsdModel(usd: nil, usd_market_cap: nil, usd_24h_vol: nil, usd_24h_change: nil, last_updated_at: nil)
EDIT: If I do:
print(String(data: undecodedData, encoding: .utf8)!)
under the line let undecodedData ...
it prints the data, so it's confirmed the problem is while decoding it with my Model, what am I doing wrong?
I have never used alamofire directly to make a network request, but seems the error is on how you decode the response, assuming undecodedData
is already containing the data you want, your current response model does not decode the "bitcoin" key, hence the struct is nil, you can change your struct to something like
struct BitcoinStats: Codable, Hashable {
let bitcoin: TokenSimplePriceCoingeckoUsdModel
}
struct TokenSimplePriceCoingeckoUsdModel: Codable, Hashable {
let usd, usd_market_cap, usd_24h_vol, usd_24h_change: Double?
let last_updated_at: Int?
}
or you might want to try to decode the value of the "bitcoin" key directly, so you can keep your current struct as is
UPDATE : Because the JSON has other keys than "bitcoin", this is my proposed solution for decoding the data dynamically without the needs to hardcode the keys: pastecode.io/s/tkim2jf0