matthewcheok / JSONCodable

Hassle-free JSON encoding and decoding in Swift
MIT License
602 stars 66 forks source link

Reflection not supported for decoding #13

Open vocaro opened 9 years ago

vocaro commented 9 years ago

The Objective-C libraries I have used for JSON, such as JSONModel, support reflection when decoding. This is good because JSON requests are often simple, while the responses are complex. For example, a REST API to search for a user may accept a single user ID in the request but return a complex user model in the response.

Reflection (mirroring) is supported in JSONCodable for encoding but not decoding. The user ID can be encoded "for free" but the decoding of the user model requires many lines of code. For example, you can do:

extension User: JSONEncodable {}

and the library will handle serialization automatically. However, the reverse doesn't work; you have to deserialize the JSON manually. For example:

extension User: JSONDecodable {
    init?(JSONDictionary: JSONObject) {
        let decoder = JSONDecoder(object: JSONDictionary)
        do {
            email = try decoder.decode("email")
            name = try decoder.decode("name")
            ...
        }
       ...
    }
}

Is there a technical issue that prevents JSONCodable from auto-deserializing JSON using JSONDecodable? I wonder if it is particularly challenging for some reason. If not, I would like to help remove this limitation.

matthewcheok commented 9 years ago

Yes I'm glad you asked! Swift requires you to initialise all properties in its initialiser and there's no dynamic way to assign values to properties automatically. Feel free to bounce around ideas though I've been stuck with this for a while.

vocaro commented 9 years ago

I'll ponder on it, but in the meantime, what about just requiring the user to make all of the model's properties Optional? Or give them all default values?

matthewcheok commented 9 years ago

That's what JSONCodable did initially but that seems like a big limitation for users to commit to. After all, Swift makes it easier to work with mutability and value types.

incognitosoftware1 commented 8 years ago

This is such a great library. Very simple and powerful!

I would like to also vote for a reflection-based decoding. If users design their objects as suggested by vocaro, perhaps there could be a method like this:

extension Company: JSONDecodable {
  init(object: JSONObject) throws {
      let decoder = JSONDecoder(object: object)
      try decoder.autoDecode()
  }
}
matthewcheok commented 8 years ago

The above challenges make it difficult to implement but you're welcome to send in a PR and help us out!