'Use List to display external data

Trying to use List to display some data from a third party API and encountering an issue trying to access the data upon performing an API call using URL session.

Using MVVM and SwiftUI.

Endpoint being called: https://alpaca.markets/docs/api-references/market-data-api/crypto-pricing-data/historical/#:~:text=Trade%20ID.-,Latest%20trade%20%23,-The%20Latest%20trade

Model:

struct ExchangeResponse: Codable, Identifiable {
    let id: UUID?
    let symbol: String
    let quote: Quote
}

// MARK: - Quote
struct Quote: Codable {
    let timestamp: String
    let exchange: String
    let bidPrice: Double
    let bidSize: Double
    let askPrice: Double
    let quoteAs: Double

    enum CodingKeys: String, CodingKey {
        case timestamp = "t"
        case exchange = "x"
        case bidPrice = "bp"
        case bidSize = "bs"
        case askPrice = "ap"
        case quoteAs = "as"
    }
}

Networking:

func getExchangePrice(exchange: String,completion: @escaping (ExchangeResponse) -> Void){
    let url = URL(string:"https://data.alpaca.markets/v1beta1/crypto/btcusd/quotes/latest?exchange=\(exchange)")!
    
    var request = URLRequest(url: url)
    
    request.setValue(alpacaApiKey, forHTTPHeaderField: "APCA-API-KEY-ID")
    request.setValue(alpacaSecretKey, forHTTPHeaderField: "APCA-API-SECRET-KEY")
    
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        guard let data = data, error == nil else {
            print(error?.localizedDescription ?? "No data")
            return
        }
  
        let exchangeResponse = try! JSONDecoder().decode(ExchangeResponse.self, from: data)
       
        print(exchangeResponse)
        DispatchQueue.main.async {
            completion(exchangeResponse)
        }
    }
    task.resume() 
}

ViewModel:

extension CryptoExchanges{
    class CryptoExchangeViewModel: ObservableObject{
        @Published var ftxuExchangeResponse = [ExchangeResponse]()
        @Published var ersxExchangeResponse = [ExchangeResponse]()
        @Published var cbseExchangeResponse = [ExchangeResponse]()
        
        init(){
            fetchExchangeData()
        }
        
        func fetchExchangeData(){
            AlpacaService().getExchangePrice(exchange: "FTXU", completion: {(ftxuExchangeResponse) in self.ftxuExchangeResponse = [ftxuExchangeResponse]})
            
            AlpacaService().getExchangePrice(exchange: "ERSX", completion: {(ersxExchangeResponse) in self.ersxExchangeResponse = [ersxExchangeResponse]})
            
            AlpacaService().getExchangePrice(exchange: "CBSE", completion: {(cbseExchangeResponse) in self.cbseExchangeResponse = [cbseExchangeResponse]})

        }
    }
    
}

View:

        List(viewModel.cbseExchangeResponse){ exchange in
            VStack{
                Text(exchange.symbol)
//                Text(exchange.quote.bidSize)
//                Text(exchange.quote.bidPrice)
//                Text(exchange.quote.askPrice)
//                Text(exchange.quote.quoteAs)
                
            }

I can access the symbol property however if I try to access any property of Quote i get a Value of type '[ExchangeResponse]' has no member 'quote' (the commented out text is having the issue). I have also tried making Quote and array and then attempting to access the first index like so, with no success. Text(exchange.quote[1].quoteAs)

I have also tried changing the @Published property like so: @Published var cbseExchangeResponse: ExchangeResponse?

and the call like so: AlpacaService().getExchangePrice(exchange: "CBSE", completion: {(cbseExchangeResponse) in self.cbseExchangeResponse = cbseExchangeResponse})

With no success.

Making quote identifiable does not work either.

Thanks



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source