Mohammed Riyadh
Mohammed Riyadh

Reputation: 1019

Swift : Codable Struct Always Nil

I Have the following JSON Response

{
    "status_code": 1000,
    "data": {
        "user_id": 1000,
        "bid": "E5PPD5E3",
        "province": 0,
        "location": "123,123"
    },
    "message": "Verified"
}

And This is my Struct

struct Basicresponse : Codable{

    var statusCode : Int!
    var message : String?
    var data : data?

    enum CodingKeys: String, CodingKey {

        case statusCode = "status_code"

    }

}

struct data : Codable{

      var province : Int
      var userID : Int
      var location : String
      var bid : String

      enum CodingKeys: String, CodingKey {

            case province, location , bid
            case userID = "user_id"

          }
  }

And

 do {


  let jsonData = try JSONDecoder().decode(Basicresponse.self, from: data!)

         if(jsonData.statusCode == 1000){

                print(jsonData)
         }else{
                 self.alert.show(target: self.view, message: jsonData.message!)
          }


            }
 catch let jsonerr {
          print("error serrializing error",jsonerr)
 }

But the result as below,

Basicresponse(statusCode: Optional(2000), message: nil, data: nil)

I don't know why both the data and the message are always nil ?! I tried the end point with Post man and its works fine but in my app its always nil, Am i missing something here ?

Any help will be much appreciated

Upvotes: 0

Views: 330

Answers (1)

Rob
Rob

Reputation: 437372

The issue is that you’ve excluded message and data from your CodingKeys. But you can add them like so:

struct Basicresponse: Codable {
    var statusCode : Int!
    var message : String?
    var data : data?

    enum CodingKeys: String, CodingKey {
        case statusCode = "status_code"
        case message, data
    }
}

The other alternative is to not supply CodingKeys at all and tell your decoder to do the snake case conversion for you.

let data = """
{
    "status_code": 1000,
    "data": {
        "user_id": 1000,
        "bid": "E5PPD5E3",
        "province": 0,
        "location": "123,123"
    },
    "message": "Verified"
}
""".data(using: .utf8)!

struct BasicResponse: Codable {
    var statusCode: Int
    var message: String?
    var data: Bid?
}

struct Bid: Codable {
    var province: Int
    var userId: Int
    var location: String
    var bid: String
}

do {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let jsonData = try decoder.decode(BasicResponse.self, from: data)

    if jsonData.statusCode == 1000 {
        print(jsonData)
    } else {
        print(jsonData.message ?? "No message")
    }
} catch let jsonError {
    print("error serializing error", jsonError)
}

I hope you don’t mind, but I’ve renamed your data type to be Bid (as data doesn’t conform to standard class naming conventions of starting with upper case letter and it’s too easily confused with the existing Data type). I don’t know if Bid is the right name, so use whatever you think is appropriate, but hopefully it illustrates the idea.

Upvotes: 2

Related Questions