How can I parse json with a dictionary in swift?

我的梦境 提交于 2021-02-20 00:48:54

问题


I have the current JSON

"updateTime": "2021-02-12T16:41:21.413Z",
"dueDate": {
  "year": 2021,
  "month": 2,
  "day": 17
},
"dueTime": {
  "hours": 4,
  "minutes": 59
},
...

How can I retrieve the values of dueDate and dueTime (including all of the data in the dictionary) using Swift?

Thanks in advance


回答1:


My suggestion is to decode the JSON with Decodable into structs and join the date and time parts to a DateComponents instance

let jsonString = """
{
    "updateTime": "2021-02-12T16:41:21.413Z",
    "dueDate": {
        "year": 2021,
        "month": 2,
        "day": 17
    },
    "dueTime": {
        "hours": 4,
        "minutes": 59
    }
}
"""

struct DueDate : Decodable {
    let year, month, day : Int
}

struct DueTime : Decodable {
    let hours, minutes : Int
}

struct Response : Decodable {
    let updateTime : String
    let dueDateComponents : DateComponents
    
    private enum CodingKeys : String, CodingKey { case updateTime, dueDate, dueTime}
    
    init(from decoder : Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        updateTime = try container.decode(String.self, forKey: .updateTime)
        let dueDate = try container.decode(DueDate.self, forKey: .dueDate)
        let dueTime = try container.decode(DueTime.self, forKey: .dueTime)
        dueDateComponents = DateComponents(year: dueDate.year, month: dueDate.month, day: dueDate.day, hour: dueTime.hours, minute: dueTime.minutes)
    }
}

let data = Data(jsonString.utf8)

do {
    let result = try JSONDecoder().decode(Response.self, from: data)
    print(result.dueDateComponents.hour!)
} catch {
    print(error)
}



回答2:


What you posted is not quite a valid JSON, but if it was like this:

let json = """
{
    "updateTime": "2021-02-12T16:41:21.413Z",
    "dueDate": {
        "year": 2021,
        "month": 2,
        "day": 17
    },
    "dueTime": {
        "hours": 4,
        "minutes": 59
    }
}
"""

then you could convert to Data

let data = json.data(using: .utf8)

And then parse using JSONSerialization:

let dict = try JSONSerialization.jsonObject(with: data!, options: []) as? [String: Any?]

And then each object inside it, becomes another JSON. For example:

let dueDate = dict?["dueDate"] as? [String: Any]
print(dueDate?["year"])



回答3:


If you have json like:

let json = """
{
    "dueDate": {
        "year": 2021,
        "month": 2,
        "day": 17
    },
    "dueTime": {
        "hours": 4,
        "minutes": 59
    }
}
"""

And you decoded it and want to convert to dict and send to server. You can easily write extension to Encodable as like:

extension Encodable {
  func asDictionary() throws -> [String: Any] {
    let data = try JSONEncoder().encode(self)
    guard let dictionary = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any] else {
      throw NSError()
    }
    return dictionary
  }
}

And use it:

let jsonData = Data(json.utf8)

let decoder = JSONDecoder()

do {
    let model = try decoder.decode(WrapperModel.self, from: jsonData)
    print(model)
    let dict = try model.asDictionary()
    print(dict)
    let dueTime = dict["dueTime"] as? [String: Any]
    print(dueTime?["hours"])
} catch {
    print(error.localizedDescription)
}


来源:https://stackoverflow.com/questions/66217999/how-can-i-parse-json-with-a-dictionary-in-swift

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!