Как использовать Decodable в Swift - PullRequest
0 голосов
/ 01 декабря 2018

В моем проекте используется бесплатный API дат.Я использую Decoadle для анализа данных json.

Здесь я создал свою struct : -

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

struct dateData: Decodable {

var quarter: Int?
var day: String?
var month: String?
}

Это мой код для использования декодера: -

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()

Но я получаю ошибку в своем коде, она идет только в блоке перехвата, и я получаю эту ошибку в моей консоли: -

ошибка сериализации ошибки typeMismatch (Swift.Array, Swift.DecodingError.Context (codingPath: [], debugDescription: «Ожидается декодировать массив, но вместо этого найден словарь.», UnderError: nil))

Я не понимаю, что яя делаю неправильно в моем коде.Пожалуйста, помогите?

Данные API: -

{сообщения: ложь, данные: {2018-01-02: {квартал: 1, день: "2", месяц: "1 ", дБ:" 2018-01-02 ", длинный:" вторник, 2 января 2018 года ", unix: 1514876400},

Ответы [ 2 ]

0 голосов
/ 01 декабря 2018
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
0 голосов
/ 01 декабря 2018

Вам нужно

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)

Поскольку корнем json является словарь, а не массив, data также является словарем

jsonData.data.forEach {
  if $0 == " 2018-01-02" {
    print($1.month)
  }
}
...