Swift - Expected to decode Array<Any> but found a dictionary instead.”, underlyingError: nil

412 views Asked by At

I'm trying to decode some json for my application and I usually do this.

My struct;

struct RequestTypes: Codable {
      let MerchRequestTypeID: Int?
      let TypeName: String?
      let LayoutID: Int?

   private enum CodingKeys: Int, CodingKey {
       case MerchRequestTypeID
       case TypeName
       case LayoutID
       }
}

And decoding;

func downloadRequestTypesJson(){
    guard let gitUrl = URL(string: "URL") else { return }
    URLSession.shared.dataTask(with: gitUrl) { (data, response
        , error) in
        guard let data = data else { return }
        do {
            let decoder = JSONDecoder()
            let RequestData = try decoder.decode(Array<RequestTypes>.self, from: data)
            DispatchQueue.main.sync {
                print(RequestData[0].MerchRequestTypeID)
                print(RequestData[1].MerchRequestTypeID)
                print(RequestData[2].MerchRequestTypeID)
            }
        } catch let err {
            print("Err", err)
        }
        }.resume()
}

This works fine for below json;

[
   {
     "MerchRequestTypeID": 1,
     "TypeName": "Stok",
     "LayoutID": 1
   },
   {
     "MerchRequestTypeID": 2,
     "TypeName": "Stand",
     "LayoutID": 2
   },
   {
     "MerchRequestTypeID": 3,
     "TypeName": "Eğitim",
     "LayoutID": 2
   }
]

But now I need to decode this json and im getting Expected to decode Array but found a dictionary instead. error;

{
  "RequestTypes": [
   {
     "MerchRequestTypeID": 1,
     "TypeName": "Stock",
     "LayoutID": 1
   },
   {
     "MerchRequestTypeID": 2,
     "TypeName": "Stand",
     "LayoutID": 2
   },
   {
     "MerchRequestTypeID": 3,
     "TypeName": "Education",
     "LayoutID": 2
   }
  ]
}

Couldn't be able to find proper way to do this. Any help is appreciated.

Edit: I am beginner on Swift. I want to know how to decode second json and how to reach its elements.

1

There are 1 answers

1
rodskagg On BEST ANSWER

That's because you are trying to decode a JSON object with a "RequestTypes" property and not an array. One solution is to create a new struct for this data structure and use that to decode your JSON:

struct RequestTypesContainer: Codable {
    let RequestTypes : [RequestTypes]

    private enum CodingKeys: String, CodingKey {
       case RequestTypes
    }
}

And then:

let RequestData = try decoder.decode(RequestTypesContainer.self, from: data)