Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Decodable in Swift?

I am using a free dates API in my project. I am using Decodable to parse the JSON data.

Here I created my struct:-

struct jsonStruct: Decodable {
var message: Bool?
var data: [dateData]
}

struct dateData: Decodable {
var quarter: Int?
var day: String?
var month: String?
}

This is my code to use the decoder:-

let jsonUrlString = "https://api.lrs.org/random-date-generator?lim_quarters=40&source=api-docs"
guard let url = URL(string: jsonUrlString) else { return }
    
URLSession.shared.dataTask(with: url) { (data, reponse, err) in
    guard let data = data  else { return }
    print(data)
        
    do {
        let jsonData = try JSONDecoder().decode([dateData].self, from: data)
        print(jsonData)
    }
    catch let jsonerr {
        print("error serrializing error",jsonerr)
    }
}.resume()

But I am getting an error in my code. It goes in the catch block only and I am getting this error in my console:-

error serrializing error typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array but found a dictionary instead.", underlyingError: nil))

I don't understand what I am doing wrong in my code.

API Data:-

{
messages: false,
data: {
2018-01-02: {
quarter: 1,
day: "2",
month: "1",
db: "2018-01-02",
long: "Tuesday, January 2nd, 2018",
unix: 1514876400
},
like image 306
Nilu Sahani Avatar asked Dec 01 '18 09:12

Nilu Sahani


2 Answers

You need

struct Root: Codable {
    let messages: Bool
    let data: [String: Datum]
}

struct Datum: Codable {
    let quarter: Int
    let day, month, db, long: String
    let unix: Int
}


let jsonData = try JSONDecoder().decode(Root.self, from: data)
print(jsonData.data.values)

As the root of the json is a dictionary not an array , also data is a dictionary

jsonData.data.forEach {
  if $0 == " 2018-01-02" {
    print($1.month)
  }
}
like image 107
Sh_Khan Avatar answered Oct 21 '22 04:10

Sh_Khan


struct Job: Decodable {
   var title: String
   var salary: Float

  init(title: String, salary: Float) {
      self.title = title
      self.salary = salary
   }

   enum CodingKeys: String, CodingKey {
     case title, salary
   }
}

struct Person: Decodable {
   var job: Job
   var firstName: String
   var lastName: String
   var age: Int

     init(job: Job, firstName: String, lastName: String, age: Int) {
       self.job = job
       self.firstName = firstName
       self.lastName = lastName
       self.age = age
   }

   enum CodingKeys: String, CodingKey {
       case job = "job_information", firstName = "firstname", lastName = 
       "lastname", age
    }
}

let rawData = """
 {
    "job_information": {
      "title": "iOS Developer",
      "salary": 5000
   },
   "firstname": "John",
   "lastname": "Doe",
    "age": 20
}
 """.data(using: .utf8)!


let person = try JSONDecoder().decode(Person.self, from: rawData)
print(person.firstName) // John
print(person.lastName) // Doe
print(person.job.title) // iOS Developer
like image 34
pramod shukla Avatar answered Oct 21 '22 03:10

pramod shukla