swiftapi

The given data was not valid JSON in swift


Api Call

@State private var receives = [Advertisment]()
func loadData() async {

    guard let url = URL(string: "https://new.demozab.com/armup/api/public/api/dashboard")
    else{
        print("iii")
        return
    }

    var request = URLRequest(url: url)

    request.setValue("U45GxRbn6NLY9Q3QomfgdWpePAjnlTE7O05wPIXL", forHTTPHeaderField: "Authorization")

    do{

        let (data,_) = try await URLSession.shared.data(from: url)
        print(data.count)
        print("\(data)")
         let decodedResponse =  try JSONDecoder().decode(Dashboardd.self, from: data)

        print("klllll")
        receives = (decodedResponse.data.advertisments )
        print(receives)



    }
    catch{
        print("\(error)")

    }



}

Model Class

struct Dashboardd: Codable {
    let success: Bool
    let message: String
    let data: DashboardDataClass
}

// MARK: - DataClass
struct DashboardDataClass: Codable {
    let quickStats: QuickStats
    let advertisments: [Advertisment]
    let receives: [Receive]
}

// MARK: - Advertisment
struct Advertisment: Codable {
    let id, cryptoCurrencyID, tradeBy: Int
    let tradeType, location, country, market: String
    let margin: String
    let tradePrice: Double
    let tradeTotal, minTransactionLimit, maxTransactionLimit, totalLimit: Int
    let totalTradeAmount, cryptoCoinAmountPrice, paymentWindow: Int
    let paymentMethod, accountDetails, additionalInformation, terms: String
    let isFeedback, status: Int
    let createdAt, updatedAt, slug: String

    enum CodingKeys: String, CodingKey {
        case id
        case cryptoCurrencyID
        case tradeBy
        case tradeType
        case location, country, market, margin
        case tradePrice
        case tradeTotal
        case minTransactionLimit
        case maxTransactionLimit
        case totalLimit
        case totalTradeAmount
        case cryptoCoinAmountPrice
        case paymentWindow
        case paymentMethod
        case accountDetails
        case additionalInformation
        case terms
        case isFeedback
        case status
        case createdAt
        case updatedAt
        case slug
    }
}

// MARK: - QuickStats
struct QuickStats: Codable {
    let buyCnt, sellCnt, openCnt, pendingCnt: Int
    let completeCnt: Int
}

// MARK: - Receive
struct Receive: Codable {
    let id, tradeOrderID, senderID, receiverID: Int
    let isTrustedUser, isDistrustedUser, feedbackScore: Int
    let message: String
    let status: Int
    let createdAt, updatedAt, username: String
    let image: String

    enum CodingKeys: String, CodingKey {
        case id
        case tradeOrderID
        case senderID
        case receiverID
        case isTrustedUser
        case isDistrustedUser
        case feedbackScore
        case message, status
        case createdAt
        case updatedAt
        case username, image
    }
}

Json Response:

{
    "success": true,
    "message": "Dashboard details",
    "data": {
        "quickStats": {
            "buyCnt": 3,
            "sellCnt": 0,
            "openCnt": 0,
            "pendingCnt": 0,
            "completeCnt": 1
        },
        "advertisments": [
            {
                "id": 8,
                "crypto_currency_id": 7,
                "trade_by": 4,
                "trade_type": "1",
                "location": "mdu",
                "country": "1",
                "market": "5",
                "margin": "15",
                "trade_price": 10,
                "trade_total": 0,
                "min_transaction_limit": 1,
                "max_transaction_limit": 16,
                "total_limit": 16,
                "total_trade_amount": 0,
                "crypto_coin_amount_price": 0,
                "payment_window": 1,
                "payment_method": "a",
                "account_details": "d",
                "additional_information": "d",
                "terms": "mm",
                "is_feedback": 0,
                "status": 0,
                "created_at": "2023-02-15",
                "updated_at": "2023-02-15T05:31:12.000000Z",
                "slug": ""
            },
            {
                "id": 5,
                "crypto_currency_id": 1,
                "trade_by": 4,
                "trade_type": "Buy",
                "location": "demo",
                "country": "98",
                "market": "74",
                "margin": "1.2",
                "trade_price": 15375.35,
                "trade_total": 0,
                "min_transaction_limit": 100,
                "max_transaction_limit": 1000,
                "total_limit": 1000,
                "total_trade_amount": 0,
                "crypto_coin_amount_price": 0,
                "payment_window": 15,
                "payment_method": "1",
                "account_details": "demo",
                "additional_information": "demo",
                "terms": "demo",
                "is_feedback": 0,
                "status": 0,
                "created_at": "2023-01-28",
                "updated_at": "2023-01-28T14:42:52.000000Z",
                "slug": "BTC"
            },
            {
                "id": 4,
                "crypto_currency_id": 1,
                "trade_by": 4,
                "trade_type": "Buy",
                "location": "demo",
                "country": "98",
                "market": "98",
                "margin": "1.2",
                "trade_price": 1254583.09,
                "trade_total": 0,
                "min_transaction_limit": 10,
                "max_transaction_limit": 100,
                "total_limit": 100,
                "total_trade_amount": 0,
                "crypto_coin_amount_price": 0,
                "payment_window": 15,
                "payment_method": "1",
                "account_details": "demo",
                "additional_information": "demo",
                "terms": "demo",
                "is_feedback": 0,
                "status": 0,
                "created_at": "2023-01-28",
                "updated_at": "2023-01-28T14:02:46.000000Z",
                "slug": "BTC"
            },
            {
                "id": 3,
                "crypto_currency_id": 3,
                "trade_by": 4,
                "trade_type": "Buy",
                "location": "demo",
                "country": "22",
                "market": "102",
                "margin": "1.2",
                "trade_price": 0.89,
                "trade_total": 0,
                "min_transaction_limit": 10,
                "max_transaction_limit": 100,
                "total_limit": 100,
                "total_trade_amount": 0,
                "crypto_coin_amount_price": 0,
                "payment_window": 15,
                "payment_method": "1",
                "account_details": "demo",
                "additional_information": "demo",
                "terms": "demo",
                "is_feedback": 0,
                "status": 0,
                "created_at": "2023-01-28",
                "updated_at": "2023-01-28T14:00:59.000000Z",
                "slug": "BUSD"
            }
        ],
        "receives": [
            {
                "id": 7,
                "trade_order_id": 11,
                "sender_id": 4,
                "receiver_id": 4,
                "is_trusted_user": 1,
                "is_distrusted_user": 0,
                "feedback_score": 4,
                "message": "test",
                "status": 1,
                "created_at": "2023-01-28T14:27:04.000000Z",
                "updated_at": "2023-02-23T05:23:02.000000Z",
                "username": "smith",
                "image": "https://new.demozab.com/armup/api/public//userpanel/images/profile.svg"
            }
        ]
    }
}

Error is :

dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around line 1, column 0." UserInfo={NSDebugDescription=Invalid value around line 1, column 0., })))

Problem in Decode the json response


Solution

  • Try this example code, using URLSession.shared.data(for: request) deduced from @Larme comment, and the following corrected models for the json data decoding. Works well for me:

    struct ContentView: View {
        @State private var receives = [Advertisment]()
        
        var body: some View {
            List(receives){ ad in
                Text(ad.accountDetails)
            }
            .task {
                await loadData()
            }
        }
    
        func loadData() async {
            let token = "W9fUlQbgowbUrGhxEbmKRbktCiinBALh2YyJ3dhn"
            guard let url = URL(string: "https://new.demozab.com/armup/api/public/api/dashboard")
            else {
                print("bad url")
                return
            }
            var request = URLRequest(url: url)
            request.addValue("application/json", forHTTPHeaderField: "Content-Type")
            request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
            do {
                let (data, _) = try await URLSession.shared.data(for: request)
                let decodedResponse = try JSONDecoder().decode(Dashboardd.self, from: data)
                receives = decodedResponse.data.advertisments
            } catch {
                print(error)
            }
        }
    }
    
    struct Dashboardd: Codable {
        let success: Bool
        let message: String
        let data: DashboardDataClass
    }
    
    // MARK: - DataClass
    struct DashboardDataClass: Codable {
        let quickStats: QuickStats
        var advertisments: [Advertisment]
        var receives: [Receive]
    }
    
    // MARK: - Advertisment
    struct Advertisment: Identifiable, Codable {
        let id, cryptoCurrencyID, tradeBy: Int
        let tradeType, location, country, market: String
        let margin: String
        let tradePrice: Double
        let tradeTotal, minTransactionLimit, maxTransactionLimit, totalLimit: Int
        let totalTradeAmount, cryptoCoinAmountPrice, paymentWindow: Int
        let paymentMethod, accountDetails, additionalInformation, terms: String
        let isFeedback, status: Int
        let createdAt, updatedAt, slug: String
    
        enum CodingKeys: String, CodingKey {
            case id, terms, status, slug, location, country, market, margin
            case cryptoCurrencyID = "crypto_currency_id"
            case tradeBy = "trade_by"
            case tradeType = "trade_type"
            case tradePrice = "trade_price"
            case tradeTotal = "trade_total"
            case minTransactionLimit = "min_transaction_limit"
            case maxTransactionLimit = "max_transaction_limit"
            case totalLimit = "total_limit"
            case totalTradeAmount = "total_trade_amount"
            case cryptoCoinAmountPrice = "crypto_coin_amount_price"
            case paymentWindow = "payment_window"
            case paymentMethod = "payment_method"
            case accountDetails = "account_details"
            case additionalInformation = "additional_information"
            case isFeedback = "is_feedback"
            case createdAt = "created_at"
            case updatedAt = "updated_at"
        }
    }
    
    // MARK: - QuickStats
    struct QuickStats: Codable {
        let buyCnt, sellCnt, openCnt, pendingCnt, completeCnt: Int
    }
    
    // MARK: - Receive
    struct Receive: Identifiable, Codable {
        let id, tradeOrderID, senderID, receiverID, status: Int
        let isTrustedUser, isDistrustedUser, feedbackScore: Int
        let message, createdAt, updatedAt, username, image: String
    
        enum CodingKeys: String, CodingKey {
            case id, username, image, message, status
            case tradeOrderID = "trade_order_id"
            case senderID = "sender_id"
            case receiverID = "receiver_id"
            case isTrustedUser = "is_trusted_user"
            case isDistrustedUser = "is_distrusted_user"
            case feedbackScore = "feedback_score"
            case createdAt = "created_at"
            case updatedAt = "updated_at"
        }
    }
    

    You will need to find from the server docs which fields are optional and adjust the code accordingly, ie add ? to it.