skip to Main Content

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

3

Answers


  1. 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"])
    
    Login or Signup to reply.
  2. 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)
    }
    
    Login or Signup to reply.
  3. 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)
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search