JSONCodable icon indicating copy to clipboard operation
JSONCodable copied to clipboard

Reflection not supported for decoding

Open vocaro opened this issue 9 years ago • 5 comments

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.

vocaro avatar Oct 20 '15 14:10 vocaro

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.

matthewcheok avatar Oct 20 '15 14:10 matthewcheok

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?

vocaro avatar Oct 20 '15 17:10 vocaro

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.

matthewcheok avatar Oct 20 '15 17:10 matthewcheok

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()
  }
}

incognitosoftware1 avatar Feb 26 '16 16:02 incognitosoftware1

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

matthewcheok avatar Feb 26 '16 16:02 matthewcheok