如何在 Swift 中使用可解码?

Posted

技术标签:

【中文标题】如何在 Swift 中使用可解码?【英文标题】:How to use Decodable in Swift? 【发布时间】:2019-05-03 07:12:48 【问题描述】:

我在我的项目中使用免费的约会 API。我正在使用Decodable 来解析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()

但我的代码出现错误。它仅在 catch 块中,我在控制台中收到此错误:-

error serrializing error typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [], debugDescription: "期望解码 Array 但找到了一个字典。", underlyingError: nil))

我不明白我在代码中做错了什么。

API 数据:-


messages: false,
data: 
2018-01-02: 
quarter: 1,
day: "2",
month: "1",
db: "2018-01-02",
long: "Tuesday, January 2nd, 2018",
unix: 1514876400
,

【问题讨论】:

JSON Decoder Type Mismatch Error的可能重复 你能展示 API 的原始响应吗?您似乎期望 JSON 有效负载将包含一个无键下的对象数组,但实际有效负载不同。 @Losiowaty... 编辑了我的问题,请检查 请(学习)阅读 JSON。这很容易。只有两种集合类型,数组([])和字典()。字典变成了结构/类。如您所见,根本没有数组。 【参考方案1】:

你需要

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)
  

【讨论】:

但是先生,我要如何使用Decodable 来做到这一点,我想这样做 Codable = Decodable + Encodable 它可以让你编码和解码,你可以让它Decodable 如果你只想要它 它给出了所有的值,但我想要一个特定的值,但我不知道该怎么做:( 我在我的控制台warning: could not execute support code to read Objective-C class data in the process. This may reduce the quality of type information available. 检查***.com/questions/50346718/…【参考方案2】:
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

【讨论】:

这是一个非常清晰且易于理解的示例。谢谢!

以上是关于如何在 Swift 中使用可解码?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 4 中引用通用的可解码结构

如何在 Swift 4 中为 JSON 编写可解码,其中键是动态的?

Swift 4 可解码的 json 数组

在 Swift 中解码引用的可打印消息

如何在 Swift 3 中使用 NSSecureCoding 解码字符串?

如何在 Swift 中使用动态键(在根级别)解码此 JSON?