-2

I've got a problem with parsing data from the server. I've got JSON which has an array of objects, something like this:

{
    "items": [
        {
            "itemType": {
                "id": 12,
                "tagId": "FCHA78558D"
            },
            "parts": [
                {
                    "partId": 52,
                    "manufacturer": "xxx"
                },
                {
                    "partId": 53,
                    "manufacturer": "xxx"
                },
                {
                    "partId": 54,
                    "manufacturer": "xxx"
                }
            ],
            "description": "yyy"
        },
        {
            "itemType": {
                "id": 13,
                "tagId": "FCHA755158D"
            },
            "parts": [
                {
                    "partId": 64,
                    "manufacturer": "xxx"
                },
                {
                    "partId": 65,
                    "manufacturer": "xxx"
                }
            ],
            "description": "zzz"
        }
    ]
}

I only want to obtain this one array of objects so I implemented this class like this:

class User : Object, Decodable {
   var items = List<Equipment>()
}

in the Alamofire I'm downloading the JSON, parsing it to data and then in do-catch block I receive an error:

let items = try JSONDecoder().decode(User.self, from: receivedValue)

error:

▿ DecodingError
  ▿ typeMismatch : 2 elements
    - .0 : Swift.Array<Any>
    ▿ .1 : Context
      ▿ codingPath : 2 elements
        - 0 : CodingKeys(stringValue: "items", intValue: nil)
        ▿ 1 : _JSONKey(stringValue: "Index 0", intValue: 0)
          - stringValue : "Index 0"
          ▿ intValue : Optional<Int>
            - some : 0
      - debugDescription : "Expected to decode Array<Any> but found a dictionary instead."
      - underlyingError : nil

That's weird because it is an array of objects for sure. I tried setting my items property to String to see the result and then I got: - debugDescription : "Expected to decode String but found an array instead." I had this error couple of times but I always managed to find the solution.

mikro098
  • 2,173
  • 2
  • 32
  • 48
  • Please include an actual JSON that you are trying to decode. The most probable cause of your issue is that `receivedValue` contains the whole JSON, which is a `Dictionary` and you only want to decode the `items` key of that `Dictionary`, but it's impossible to tell for sure without seeing the full JSON response and the value of `receivedValue`. – Dávid Pásztor Apr 19 '18 at 21:28
  • @DávidPásztor I've just edited the question. This response from server is very long but there is the most important part. – mikro098 Apr 19 '18 at 21:46

1 Answers1

1

I suppose you were using the List conditional conformance to Decodable from my answer to your previous question. I don't fully understand why it doesn't work in this specific case, but I'll investigate.

Until then, you can make decoding work by manually implementing the init(from decoder:Decoder) function.

class User : Object, Decodable {
    let items = List<Equipment>()

    private enum CodingKeys: String, CodingKey {
        case items
    }
    required convenience init(from decoder:Decoder) throws {
        self.init()
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let itemsArray = try container.decode([Equipment].self, forKey: .items)
        self.items.append(objectsIn: itemsArray)
    }
}
Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
  • @codddeer123 that's quite weird, I'm not sure why that happens, but I've updated my answer with a workaround that I've tested and is working correctly. In the meantime i'll investigate why the `List` extension is not working in this specific case. – Dávid Pásztor Apr 20 '18 at 14:18
  • I changed this line from `let items = List()` to `var items: [Equipment]!` and I can see that array count is not 0 so there must be some problem with List edit: ok, this workaround works, thanks. Very weird problem – mikro098 Apr 20 '18 at 14:19