How to convert a Swift object to a dictionary

JL Gradley picture JL Gradley · Aug 12, 2015 · Viewed 27.6k times · Source

I'm relatively new to iOS programming. However, I would have assumed that Swift would have an automated way of converting objects to JSON and vice versa. That being said, I have found several libraries that can do this.

HOWEVER...

It seems that no matter how you post data to a web service (even using something like AlamoFire), the requests must be a dictionary. All these forums show examples of how easy it is to convert the returned JSON string to objects. True. But the request needs to be manually coded. That is, go through all of the object properties and map them as a dictionary.

So my question is this: Am I missing something? Have I got this all wrong and there's a super-easy way to either (a) send JSON (instead of a dictionary) in the REQUEST or (b) convert an object automatically to a dictionary?

Again, I see how easy it is to deal with a JSON response. I'm just looking for an automatic way to convert the request object I want to post to a web service into a format that a library like AlamoFire (or whatever) requires. With other languages this is fairly trivial, so I'm hoping there's an equally easy and automated way with Swift.

Answer

fencingCode picture fencingCode · Sep 20, 2015

I must disagree with @Darko.

In Swift 2,

use protocol oriented programming and the simple reflection offered by Mirror class :

protocol JSONAble {}

extension JSONAble {
    func toDict() -> [String:Any] {
        var dict = [String:Any]()
        let otherSelf = Mirror(reflecting: self)
        for child in otherSelf.children {
            if let key = child.label {
                dict[key] = child.value
            }
        }
        return dict
    }
}

then you can use this protocol with your request class and produce the desired dictionary :

class JsonRequest : JSONAble {
    var param1 : String?
    // ...
}

let request = JsonRequest()
// set params of the request
let dict = request.toDict()
// use your dict