Home > Software design >  JSON data decoding on swift using Decodable and codingKeys and convertFromSnakeCase
JSON data decoding on swift using Decodable and codingKeys and convertFromSnakeCase

Time:03-02

I have a JSON data that I want to parse on my swift project, JSON data:

{
            "receipt_id": 9498,
            "status": "ACCEPTED",
            "value": 100,
            "promotionName": "Kampagne ",
            "promotionId": 2062,
            "imageUrl": "https://image.png",
            "uploaded": "2022-02-22T11:58:21 0100"
        }

On my project I have this code:

struct Receipt: Decodable {
    let receiptId: Int?
    let status: ReceiptStatus
    let rejectionReason: String?
    let value: Cent?
    let promotionName: String
    let promotionId: Int
    let imageUrl: URL
    let uploaded: Date

    enum CodingKeys: String, CodingKey {
        case receiptId = "receipt_id"
        case status = "status"
        case rejectionReason = "rejectionReason"
        case value = "value"
        case promotionName = "promotionName"
        case promotionId = "promotionId"
        case imageUrl = "imageUrl"
        case uploaded = "uploaded"
    }
}

When decoding JSON data this error appears:

'Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "imageUrl", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "receipts", intValue: nil), _JSONKey(stringValue: "Index 1", intValue: 1)], debugDescription: "No value associated with key CodingKeys(stringValue: "imageUrl", intValue: nil) ("imageUrl"), converted to image_url.", underlyingError: nil))'

On decoding the JSON data I use convertFromSnakeCase but sometimes I don't want to follow this method for decoding so I force it inside codingKeys and that error appears

CodePudding user response:

Try this:

struct Receipt: Codable {
    let receiptID: Int
    let status: String
    let value: Int
    let promotionName: String
    let promotionID: Int
    let imageURL: String
    let uploaded: Date

    enum CodingKeys: String, CodingKey {
        case receiptID = "receipt_id"
        case status, value, promotionName
        case promotionID = "promotionId"
        case imageURL = "imageUrl"
        case uploaded
    }
}

CodePudding user response:

It'wrong is a let imageUrl: URL, let uploaded: Date, let status: ReceiptStatus

Because the value of imageUrl , uploaded, status is String, If you using Date, URL and custom enum type of your model. Please using

public init(from decoder: Decoder) throws

to cast new type you want or you set Optional to imageUrl and uploaded, status.

Apple Document

  • Related