3

How can I decode data to a structure using Alamofire and SwiftyJSON? My attempts give me errors like that

"No value associated with key CodingKeys(stringValue: \"user\", intValue: nil)

Here is my code, my try doesn't give me the result when I use non-optional values, they respond to me with NIL values

Alamofire.request(url, method: .post, parameters: params, encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
            if response.data != nil {
                switch response.result {
                case.failure( let error):
                    print(error)
                case.success(let val):
                    var json = JSON(val)
                    print(json)
                    guard let data = response.data else {return}
                    do {
                        let root = try JSONDecoder().decode(MainInfo.self, from: data)
                        print(root.submodel)
                    }
                    catch {
                        print("Bigerror")
                        print(error)
                    }

This is my structure

struct user: Codable {
    var push_id:String?
    var name:String?
    var id:String?
    var role_id:String?
    var taxi_park_id:Int?
    var car_number:String?

    enum CodingKeys:String,CodingKey {
        case push_id = "push_id"
        case name = "name"
        case id = "id"
        case role_id = "role_id"
        case taxi_park_id = "taxi_park_id"
        case car_number = "car_number"     
    }
}

struct MainInfo : Decodable {
    let model: String?
    let submodel: String?
    let user:user
    enum CodingKeys:String,CodingKey {
        case model = "model"
        case submodel = "submodel"
        case user = "user"

    }
}

This is my pretty printed json

{
  "facilities" : [

  ],
  "model" : "AMC",
  "taxi_park" : "Taxi +",
  "submodel" : "Gremlin",
  "user" : {
    "role_id" : 2,
    "push_id" : "dW7Cy-ItcDo:APA91bH62zJJKKz0t9VxP29H0iE2xhnQH0hDvKpGaHc5pknuTuZq2lMaj-EapQlN3O4dJF0ysSuCNOeb-2SdJaJaLIZcwHD3CCpeNpz6UVeGktoCm2ykL2rNXF5-ofQckvz1xTvVO0V6",
    "taxi_park_id" : 0,
    "id" : 3,
    "name" : "China",
    "car_number" : "X123OOO"
  }
}
Vikrant
  • 4,920
  • 17
  • 48
  • 72
  • Change `var id:String?` to `var id: Int`. `"id" : 3` in your JSON, the value for `"id"` is a number, not a string. By the way, when you use `Codable`, you have no need to use SwiftyJSON. – OOPer Oct 11 '18 at 06:06
  • "facilities" what are the possible values for it – Mohmmad S Oct 11 '18 at 06:11
  • i change it , but i'm get "keyNotFound(CodingKeys(stringValue: "user", intValue: nil)" –  Oct 11 '18 at 06:12
  • i should Codable all variables of json ? –  Oct 11 '18 at 06:13
  • @ЧингизКуандык, sorry I missed `"role_id" : 2`, it's also a number. You need `var role_id: Int?`. – OOPer Oct 11 '18 at 06:24
  • @ЧингизКуандык, **Codable all variables of json ?**. YES. With just a glance to your JSON example, your JSON is well structured to work with `Codable`. Dispose SwiftyJSON and go along with `Codable`. – OOPer Oct 11 '18 at 06:28
  • i add all values to structure bui i get this shit keyNotFound(CodingKeys(stringValue: "user", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"user\", intValue: nil) (\"user\").", underlyingError: nil)) –  Oct 11 '18 at 07:04
  • @ЧингизКуандык, please show your latest code. You may be missing something or you are testing with another data than you have shown. I have confirmed that with 2 fixes I mentioned above, the data you have shown successfully decoded to `MainInfo`. – OOPer Oct 11 '18 at 07:52
  • @ЧингизКуандык, seems like a problem is in your data. Can you print `String(data: data, encoding: .utf8)`? – Sviatoslav Yakymiv Oct 11 '18 at 08:51

2 Answers2

1

First of all your question has nothing to do with SwiftyJSON as you are using Codable.

Second of all name the structs with starting capital letter (User), that avoids confusion like let user : user

The error is misleading. All .._id values except push_id are Int rather than String. It's very easy to distinguish strings from all other types: Strings are always wrapped in double quotes.

And if you pass the convertFromSnakeCase key decoding strategy you don't need CodingKeys at all

struct MainInfo : Decodable {
    let model : String
    let submodel : String
    let user : User
}

struct User: Decodable {
    let pushId : String
    let name : String
    let id : Int
    let roleId : Int
    let taxiParkId : Int
    let carNumber : String
}

...

do {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let root = try decoder.decode(MainInfo.self, from: data)
    print(root.submodel)
} catch { print(error) }
vadian
  • 274,689
  • 30
  • 353
  • 361
0

Try this code, also a simple tip, we use coding keys in swift because sometimes we have to receive an inconvenient parameter keys but we also want to use it simple and clearly in the struct therefore CodingKeys are helpful in your case you using CodingKeys to decode the same parameter name i added the following taxiPark propriety to give you a hint on why they are useful, for example: i want to parse a JSON that have a key called

Person_ID_From_School  

with coding keys i can do that with a better naming simple as personId and so on

 struct MainInfo : Decodable {
        let model: String?
        let submodel: String?
        let user:user
        let taxiPark: String? 
        let facilities: [String?]?
        enum CodingKeys:String,CodingKey {
            case model = "model"
            case submodel = "submodel"
            case user = "user"
            case taxiPark = "taxi_park"
            case facilities = "facilities"

        }
    }
Mohmmad S
  • 5,001
  • 4
  • 18
  • 50