-2

In my project I want to build a easy Crypto price app. So I want to get information from the Coinlore (https://www.coinlore.com/cryptocurrency-data-api) API. I made a request to the API and in the following I have to decode the JSON. But my problem is that the path to e.g. the price of the coin is "0.price_usd". But i can not create a struct named "0". This is how the JSON looks:enter image description here

Can anyone please help me? Appreciate it!!!

David
  • 193
  • 1
  • 8
  • I tried it, but my JSON is not stored in a JSON String, rather in a Array. So for me it doesn´t work, but if it should work please tell me how – David Jun 23 '21 at 10:03
  • `[String: YourDecodableStruct]` should do the trick at some point... – Larme Jun 23 '21 at 10:12
  • If it's an `Array` then decode it as an `Array`, you don't need a `struct` named `0`. This is pretty basic stuff and there's plenty of resources on how to decode JSON with `Codable`, and even tools that generate the required types for you https://app.quicktype.io – EmilioPelaez Jun 23 '21 at 10:13

2 Answers2

2

Looking at their sample response

{
  "data": [
    {
      "id": "90",
      "symbol": "BTC",
      "name": "Bitcoin",
      "nameid": "bitcoin",
      "rank": 1,
      "price_usd": "6456.52",
      "percent_change_24h": "-1.47",
      "percent_change_1h": "0.05",
      "percent_change_7d": "-1.07",
      "price_btc": "1.00",
      "market_cap_usd": "111586042785.56",
      "volume24": 3997655362.9586277,
      "volume24a": 3657294860.710187,
      "csupply": "17282687.00",
      "tsupply": "17282687",
      "msupply": "21000000"
   }],
  "info": {
    "coins_num": 1969,
    "time": 1538560355
  }
}

*note it has a closing ']' missing

you can create a swift model like so using

import Foundation

let json = "{\r\n  \"data\": [\r\n    {\r\n      \"id\": \"90\",\r\n      \"symbol\": \"BTC\",\r\n      \"name\": \"Bitcoin\",\r\n      \"nameid\": \"bitcoin\",\r\n      \"rank\": 1,\r\n      \"price_usd\": \"6456.52\",\r\n      \"percent_change_24h\": \"-1.47\",\r\n      \"percent_change_1h\": \"0.05\",\r\n      \"percent_change_7d\": \"-1.07\",\r\n      \"price_btc\": \"1.00\",\r\n      \"market_cap_usd\": \"111586042785.56\",\r\n      \"volume24\": 3997655362.9586277,\r\n      \"volume24a\": 3657294860.710187,\r\n      \"csupply\": \"17282687.00\",\r\n      \"tsupply\": \"17282687\",\r\n      \"msupply\": \"21000000\"\r\n   }],\r\n  \"info\": {\r\n    \"coins_num\": 1969,\r\n    \"time\": 1538560355\r\n  }\r\n}"


struct Tokens: Codable {
    let data: [SomeData]
}

struct SomeData: Codable {
    let priceUsd: String
    enum CodingKeys: String, CodingKey {
        case priceUsd = "price_usd"
    }
}


let tokens = try? JSONDecoder().decode(Tokens.self, from: json.data(using: .utf8)!)
print(tokens?.data.first?.priceUsd)

// edited my earlier answer, run the above it should get you your price
  • Thank you for your response, but when I am trying your solution I get an error: typeMismatch(Swift.Dictionary, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary but found an array instead.", underlyingError: nil)) Do you know what it exactly means and where the issue is? – David Jun 24 '21 at 06:31
  • 1
    revised the code above, i used an online code generator and it had some types messed up, the above snippet should get your what you want, try it in a playground. Enjoy – Umar Cheema Jun 25 '21 at 16:43
0

With Alamofire and Decodable protocol you can easily decode this:

func fetchExchangeData() {
        let url = "https://api.coinlore.net/api/exchange/?id=5"
        
        struct Root: Decodable {
            let data: Datas
            let pairs: [Pairs]
            
            private enum CodingKeys : String, CodingKey {
                case data = "0", pairs
           }
        }
        struct Datas: Decodable {
            let date: String
            let name: String
            let url: String
            
            private enum CodingKeys : String, CodingKey {
                case date = "date_live", name, url
           }
        }
        struct Pairs: Decodable {
            let base: String?
            let price: Double?
            let priceUsd: Double?
            let quote: String?
            let time: Double?
            let volume: Double?
            
            private enum CodingKeys : String, CodingKey {
                case base, price, priceUsd = "price_usd", quote, time, volume
           }
        }
        
        AF.request(url, method: .get).responseDecodable { (response: DataResponse<Root, AFError>) in
            switch response.result {
            case .success(let result):
                for pair in result.pairs {
                    print(pair.priceUsd)
                }
            case .failure(let error):
                print(error)
            }
        }
    }

Just for the sample, we print out all the price_usd value. You can create a model for pairs, and save them into an array.

Dris
  • 881
  • 8
  • 19