1

What is the data model corresponding to the below json?

{ 
   dog:
   {
      type: "dog",
      logoLocation: "url1"
   },
   pitbull: 
   {
       type: "pitbull",
       logoLocation: "url2"
    }
}

This is a dictionary of dictionaries So I tried,

class PhotosCollectionModel: Codable {
    var photoDictionary: Dictionary<String, PhotoModel>?
}

class PhotoModel: Codable {
    var type: String?
    var logoLocation: String?
}

But it is not working. Any help please?

vivin
  • 992
  • 1
  • 8
  • 24

2 Answers2

3

You need

struct Root: Codable {
    let dog, pitbull: Dog
}

struct Dog: Codable {
    let type, logoLocation: String  // or let logoLocation:URL
}

Correct json

{
    "dog":
    {
        "type": "dog",
        "logoLocation": "url1"
    },
    "pitbull":
    {
        "type": "pitbull",
        "logoLocation": "url2"
    }
}

for dynamic

just use [String:Dog] in Decoder

    do {

        let res  = try JSONDecoder().decode([String:Dog].self,from:data)
    }
    catch {

        print(error)
    }
Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87
  • If there are n elements like dog, pitbull? – vivin Feb 17 '19 at 15:51
  • Giving it as array try JSONDecoder().decode([String:Dog].self,from:data) here works. But when i create a model and separately it doesn't work. May i know why? – vivin Feb 17 '19 at 16:18
  • the `[]` in `[String:Dog]` doesn't mean it's an array , the result is a dictionary , for Array `[[String:Dog]]` that won't decode with your current json structure – Shehata Gamal Feb 17 '19 at 16:29
0

I would skip the first class and keep

class PhotoModel: Codable {
    var type: String
    var logoLocation: String
}

and then decode it like a dictionary

do {
    let decoder = JSONDecoder()
    let result = try decoder.decode([String: PhotoModel].self, from: data)
    result.forEach { (key,value) in
        print("Type: \(value.type), logo: \(value.logoLocation) (key: \(key))")
    }
} catch  {
    print(error)
}

Outputs

Type: dog, logo: url1 (key: dog)
Type: pitbull, logo: url2 (key: pitbull)

Are really both attributes optional, if not I suggest you remove any unnecessary ? in PhotoModel (I did)

Joakim Danielson
  • 43,251
  • 5
  • 22
  • 52
  • @ArashEtemad I don't understand your comment, could you clarify? – Joakim Danielson Feb 17 '19 at 16:07
  • .convertFromSnakeCase should be .convertFromCamelCase – Arash Etemad Feb 17 '19 at 16:09
  • @ArashEtemad First of all setting that property is not needed here, a copy & paste error if anything and secondly it should be `.convertFromSnakeCase.` and nothing else – Joakim Danielson Feb 17 '19 at 16:37
  • I know this is not required but snakeCase is wrong here and it should be .useDefaultKeys in this answer, you sure you know difference between camel case and snake case? – Arash Etemad Feb 17 '19 at 16:52
  • @ArashEtemad there isn’t even such a thing as `.convertFromCamelCase` so give it a break. I did remove setting the property since it wasn’t relevant here in the first place – Joakim Danielson Feb 17 '19 at 17:22