AndiAna
AndiAna

Reputation: 964

My API call is broken with unknown error. What is the cause of this?

The following code used to work until a few days ago. I have no idea what updated, maybe new 14.4? But it suddenly stopped working today with a nondescript error and i dont know what is wrong here.

FetchStockAPIApp.swift

import SwiftUI

@main
struct FetchStockAPIApp: App {
    @StateObject public var stocks = TFViewModel()
    
    var body: some Scene {
        WindowGroup {
            ContentView(stocks: stocks)
        }
    }
}

ContentView.swift

import SwiftUI

struct ContentView: View {
    @ObservedObject var stocks : TFViewModel
    
    let isSSL = false
    public var url : String = "http://10.0.0.41:8111/xyz123"
    public var sslurl: String = "https://domain.name:8100/xyz123"
    
    var body: some View {
        ScrollView {
            ForEach(stocks.tfstocks!, id: \.recid) { item in
                Text("123")
            }
        }
        .onAppear {stocks.fetchData(apiUrl: isSSL ? sslurl : url)}
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(stocks: TFViewModel())
    }
}

TFDataModel.swift

import SwiftUI

struct TFStock: Codable, Hashable {
    var recid = UUID()
    var symbol: String
    var Close: Double
}


class TFViewModel: ObservableObject {
    @Published var tfstocks: [TFStock]? = [TFStock]()
    
    func fetchData(apiUrl: String) {
        
        guard let url = URL(string: apiUrl) else {
            print("URL is not valid")
            return
        }
        
        let request = URLRequest(url: url)
        
        URLSession.shared.dataTask(with: request) {
            data, response, error in
            if let data = data {  // data is Optional, so
                // you need to unwrap it
                if let decodedResult = try?
                    JSONDecoder().decode(
                        [TFStock].self, from: data) {
                    // decoding is successful
                    DispatchQueue.main.async {
                        // assign the decoded articles to
                        // the state variable
                        self.tfstocks = decodedResult
                    }
                    //print(decodedResult)
                    return
                }
            }
            print("Error: \(error?.localizedDescription ?? "Unknown error in API Fetch")")
        }.resume()
    }
}

remove the XXX from the SSL url to make that API call work in the code. I would be really grateful if someone could help me out here.

you need to turn isSSL = true to ON so that you use the domain name, since the other IP is just the same API on my local network.

Upvotes: 0

Views: 793

Answers (1)

Tushar Sharma
Tushar Sharma

Reputation: 2882

I would suggest you to read more about Codable protocol and what it’s used for. You can refer below link.

https://medium.com/@pleelaprasad/codable-protocols-in-swift-76f8b088c483.

The catch block prints below error for your code.

keyNotFound(CodingKeys(stringValue: "recid", intValue: nil), Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "No value associated with key CodingKeys(stringValue: "recid", intValue: nil) ("recid").", underlyingError: nil)) Error: Unknown error in API Fetch

I have verified the same using postman.

Below is the working solution.

import SwiftUI

struct ContentViewsss: View {
    @ObservedObject var stocks : TFViewModel
    
    let isSSL = true
    public var url : String = "http://10.0.0.41:8111/xyz123"
    public var sslurl: String = "https://domain.name/xyz123"
    
    var body: some View {
        ScrollView {
            ForEach(stocks.tfstocks!, id: \.recid) { item in
                Text(item.symbol)
            }
        }
        .onAppear {stocks.fetchData(apiUrl: isSSL ? sslurl : url)}
    }
}

struct TFStock: Codable, Hashable {
    var recid = UUID()
    var symbol: String
    var Close: Double
    
    private enum CodingKeys : String, CodingKey {
        case  symbol, Close
    }
}


class TFViewModel: ObservableObject {
    @Published var tfstocks: [TFStock]? = [TFStock]()
    
    func fetchData(apiUrl: String) {
        
        guard let url = URL(string: apiUrl) else {
            print("URL is not valid")
            return
        }
        
        let request = URLRequest(url: url)
        
        URLSession.shared.dataTask(with: request) {
            data, response, error in
            if let data = data {  // data is Optional, so
                // you need to unwrap it
                
                do{
                    let decodedResult = try
                        JSONDecoder().decode(
                            [TFStock].self, from: data)
                    // decoding is successful
                    DispatchQueue.main.async {
                        // assign the decoded articles to
                        // the state variable
                        self.tfstocks = decodedResult
                    }
                    //print(decodedResult)
                    return
                    
                }catch let error{
                    print(error)
                }
                
            }
            print("Error: \(error?.localizedDescription ?? "Unknown error in API Fetch")")
        }.resume()
    }
}

Upvotes: 1

Related Questions