3

I am trying to convert a swift object to JSON, I have seen these SO questions 1 & 2, but I could not apply it to my code.

I have a swift object of type [String : DailyTimes] which I would like to convert it back to JSON data in a pure Swift 3 way, without any libraries.

Below is my custom class:

class AvailabilityTimes:{

    struct Times{
        var startTime : String?
        var endTime   : String?


    }

    struct DailyTimes{
        let weekday : String
        var available : Bool
        var times = [Times]()
        mutating func update(times: [Times]){
            self.times = times
        }

    }
}

The converted JSON data (from Swift object) would look something like this:

[
     "Monday": [ "weekday" : "Monday",
                 "available" : true,
                 "times": [
                     ["startTime": "9:00 AM", "endTime": "1:30 PM" ],
                     ["startTime": "2:30 PM", "endTime": "6:00 PM" ],
                     ["startTime": "7:30 PM", "endTime": "9:00 PM" ]
                 ]
     ],
     "Tuesday": [ "weekday" : "Tuesday",
                 "available" : true,
                 "times": [
                     ["startTime": "9:00 AM", "endTime": "6:00 PM" ]
                 ]
                 ]
     ]

My unsuccessful attempt to convert [String : DailyTimes] to JSON data

Step 1: Added convertToDictionary function in both structs.

class AvailabilityTimes:{

    struct Times{
        var startTime : String?
        var endTime   : String?

        func convertToDictionary() -> Dictionary<String, Any> {
            return [
                "startTime" : self.startTime,
                "endTime"   : self.endTime
            ]
        }
    }

    struct DailyTimes{
        let weekday : String
        var available : Bool
        var times = [Times]()
        mutating func update(times: [Times]){
            self.times = times
        }

        func convertToDictionary() -> Dictionary<String, Any> {
            return [
                "weekday"   : self.weekday,
                "available" : self.available,
                "times"     : self.times
            ]
        }

    }
} 

This is where I am unsuccessfully trying to convert to JSON data.

Step 2: Function that converts to JSON data

func convertTimesObjectToJSON(timesObject: [String : DailyTimes]){

                for (key, value) in timesObject{

                    let dictionary =  value.convertToDictionary

                    print("dictionary", dictionary)
                    do{
                        let theJSONData = try JSONSerialization.data(withJSONObject: dictionary, options: .prettyPrinted)
                    } catch let error{
                        print("error: \(error)")
                    }



                }

            }
1
  • change this line let dictionary = value.convertToDictionary() Commented Aug 27, 2017 at 17:42

2 Answers 2

5

This method:

JSONSerialization.data(withJSONObject: dictionary, options: .prettyPrinted)

requires that dictionary to be a "property list". And a this:

        [
            "weekday"   : self.weekday,
            "available" : self.available,
            "times"     : self.times
        ]

Is not a property list.

Why? Because self.times is of type [Times], which is not a property list type. You need to call self.times.map{$0.convertToDictionary()) here so as to convert times to a property list.

func convertToDictionary() -> Dictionary<String, Any> {
    return [
        "weekday"   : self.weekday,
        "available" : self.available,
        "times"     : self.times.map{$0.convertToDictionary())
    ]
}
Sign up to request clarification or add additional context in comments.

Comments

2

Try this :

struct DailyTimes{
    let weekday : String
    var available : Bool
    var times = [Times]()
    mutating func update(times: [Times]){
        self.times = times
    }

    func convertTimesToDictionary() -> [Any] {
        var timeDict:[Any] = []
        self.times.forEach({ timeDict.append($0.convertToDictionary())})
        return timeDict
    }

    func convertToDictionary() -> Dictionary<String, Any> {
        return [
            "weekday"   : self.weekday,
            "available" : self.available,
            "times"     : self.convertTimesToDictionary()
        ]
    }
}

Function convert to json :

func convertToJSONObject(timesObject: [String : DailyTimes]) -> [String:AnyObject] {
    var dailyTimesObject:[String:AnyObject] = [:]
    for (key, value) in timesObject {
        dailyTimesObject.updateValue(value.convertToDictionary() as AnyObject, forKey: key)
    }
    return dailyTimesObject
}

func convertTimesObjectToJSON(timesObject: [String : DailyTimes]){
    do{
        let theJSONData = try JSONSerialization.data(withJSONObject: convertToJSONObject(timesObject: timesObject), options: .prettyPrinted)
        print(String(data: theJSONData, encoding: String.Encoding.utf8)!)
    } catch let error{
        print("error: \(error)")
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.