Search code examples
iosjsonswiftparsingurlsession

Error trying to parse JSON using URLSession in swift


I'm trying to parse a test JSON from a http adress, but I get an error saying that

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

The JSON looks like this. It has been validated, so it should work ok:

{
  "work": [
    {
      "name": "Jocke",
      "job": "Developer",
      "date": "1985-12-30T00:00:00+0000",
      "best_book": {
        "id": 33245,
        "title": "DiscWorld",
        "author": {
          "id": 345,
          "name": "Terry Prattchet"
        }
      }
    },
    {
      "name": "Bob",
      "job": "Construction worker",
      "date": "2010-01-30T00:00:00+0000",
      "best_book": {
        "id": 375802,
        "title": "Ender's Game (Ender's Saga, #1)",
        "author": {
          "id": 589,
          "name": "Orson Scott Card"
        }
      }
    }
  ]
}

The code looks like this:


struct People: Codable {
    let name: String
    let job: String

    enum OuterKey: String, CodingKey {
        case work = "work"
    }

    enum codingKeys: String, CodingKey {
        case name = "name"
        case job = "job"
    }

    init(decoder: Decoder) throws {
        let outerContainer = try decoder.container(keyedBy: OuterKey.self)
        let innerContainer = try outerContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .work)
        self.name = try innerContainer.decode(String.self, forKey: .name)
        self.job = try innerContainer.decode(String.self, forKey: .job)
    }

}

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        guard let url = URL(string: "https://api.myjson.com/bins/fe2eo") else { return }

        URLSession.shared.dataTask(with: url) { (data, response, error) in
            guard let data = data else { return }

            do {
                let jsonDecoder = JSONDecoder()
                jsonDecoder.keyDecodingStrategy = .convertFromSnakeCase

                let decodedJson = try! jsonDecoder.decode([People].self, from: data)
            }
        }.resume()
    }
}

I'm just trying to grasp the first two keys as of now, just to see if it works. But it doesn't even get past name.


Solution

  • just try this

    struct Work:Codeable {
      let work:[People]
    }
    
    struct People: Codable {
        let name: String
         let job: String
        }
    
         do {
              let jsonDecoder = JSONDecoder()
              let decodedJson = try jsonDecoder.decode(Work.self, from: data)
             }
       catch {
               print(error)
              }
    

    if you have same name as json keys you don't need to use codingkeys