skip to Main Content

I am making an API call with URLSession and I am getting the error like: The data couldn’t be read because it isn’t in the correct format I don’t know why it is happeing.
Even I am able to print the response in string format but not getting parsed.

API calling method

func getDashboardCountReq() {
    guard let url = URL(string: urlString) else {
        return
    }
    var request = URLRequest(url: url)
    request.httpMethod = "GET"
    request.addValue("application/json", forHTTPHeaderField: "content-type")
    
    let userDetails = UserInfo.shared.getCurrentUserDetails()
    
    if let authToken = userDetails?.authToken {
        let headers = ["Content-Type": "application/json",
            "Authorization": "Bearer " + authToken]
        request.allHTTPHeaderFields = headers
    }
    
    URLSession.shared.dataTask(with: request) { (data,response,error) in
        do {
            
            if let data = data {
                let responseString = String(data: data, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue))
                print("responseString (responseString)")
                
                do {
                    let f = try JSONDecoder().decode([DashboardResponseData].self, from: data)
                    print(f.count)
                    
                } catch {
                    print("1232 (error.localizedDescription)")
                }
                
                
            } else {
                print("LoginViewModel-> no data found")
            }
        } catch(let error) {
            print("Error A123 (error.localizedDescription)")
        }
    }.resume()
    
}

// Model

struct DashboardResponseData: Codable, Identifiable {
    let id = UUID()
    var approvedrc: String
    var pendingpo: String?
    var assets: String?
    var approvedprs: String?
    var pendingrc: String?
    var approvedpo: String?
    var pendingprs: String?
    var tickets: String?
    
    enum CodingKeys: String, CodingKey {
        case approvedrc = "approvedrc"
        case pendingpo  = "pendingpo"
        case approvedprs = "approvedprs"
        case pendingrc    = "pendingrc"
        case approvedpo = "approvedpo"
        case pendingprs = "pendingprs"
        case tickets = "tickets"
    }
}

String Response

[{"approvedrc":41,"pendingpo":566,"assets":37956,"approvedprs":1040,"pendingrc":8,"approvedpo":1650,"pendingprs":1709,"tickets":137872}]

// Log

enter image description here

2

Answers


  1. All the values in DashboardResponseData are declared as strings, but are integers in the JSON, so you should either parse them as Int, or add quotes around them in the JSON.

    There it works :

    import Foundation
    
    let json = "[{"approvedrc":41,"pendingpo":566,"assets":37956,"approvedprs":1040,"pendingrc":8,"approvedpo":1650,"pendingprs":1709,"tickets":137872}]"
    
    struct DashboardResponseData: Codable, Identifiable {
        let id = UUID()
        var approvedrc: Int
        var pendingpo: Int?
        var assets: Int?
        var approvedprs: Int?
        var pendingrc: Int?
        var approvedpo: Int?
        var pendingprs: Int?
        var tickets: Int?
        
        enum CodingKeys: String, CodingKey {
            case approvedrc = "approvedrc"
            case pendingpo  = "pendingpo"
            case approvedprs = "approvedprs"
            case pendingrc    = "pendingrc"
            case approvedpo = "approvedpo"
            case pendingprs = "pendingprs"
            case tickets = "tickets"
        }
    }
    
    
    let f = try JSONDecoder().decode([DashboardResponseData].self, from: json.data(using: .utf8)!)
    print(f.count)
    

    Also, note that you can simplify this :

    let responseString = String(data: data, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue))
    

    which is completely redundant (String.Encoding(rawValue: String.Encoding.utf8.rawValue)) can simply be String.Encoding.utf8) to this :

    let responseString = String(data: data, encoding: .utf8)
    

    because enum type String.Encoding is deducted as it is the expected type of this argument.

    Login or Signup to reply.
  2. As mentioned your data are Int, and you are also missing the assets in CodingKeys. Try something like this:

    struct DashboardResponseData: Codable, Identifiable {
        let id = UUID()
        let approvedrc, pendingpo, assets, approvedprs: Int?
        let pendingrc, approvedpo, pendingprs, tickets: Int?
        
        enum CodingKeys: String, CodingKey {
            case approvedrc,pendingpo,assets,approvedprs,pendingrc,approvedpo,pendingprs,tickets
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search