Home > Mobile >  Why JSON response is not getting parsed?
Why JSON response is not getting parsed?

Time:10-27

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

CodePudding user response:

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
    }
}

CodePudding user response:

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.

  • Related