matthewcheok / JSONCodable

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

toJSON() improvement #14

Open lucatorella opened 9 years ago

lucatorella commented 9 years ago

Most of the times the default implementation of toJSON() is great, so you don't need to implement that function. Anyway if you want to change the name of just one property, you need to implement toJSON() for all the properties. It would be nice to add a method that it will ask for mapping some properties name, otherwise will use the default behavior.

example: My object has a oneProperty property. And the server wants a one_property property. I'd like a method like:

func mapPropertyName(name: String) -> String? {
   if name == "oneProperty" { 
       return "one_property" 
   } else {
       return nil // use default implementation 
   }
}
matthewcheok commented 9 years ago

What do you think about calling super and then making the change for one property? Debatably it's less efficient but Swift doesn't have optional protocol methods so we would have to implement mapPropertyName if we don't need it?

lucatorella commented 8 years ago

true, there is no optional methods, but you can define a default implementation via protocol extension, achieving the same result. What do you think?

tomlokhorst commented 8 years ago

Swift sort of has optional protocol methods by creating default implementations in an extension.

For this example, you could change the protocol to:

public protocol JSONEncodable {
    func toJSON() throws -> AnyObject
    func mapPropertyName(name: String) -> String?
}

And add a default implementation:

public extension JSONEncodable {
    func mapPropertyName(name: String) -> String? {
        return nil
    }
}

Then in toJSON, you write: let label = mapPropertyName(defaultLabel) ?? defaultLabel Users can optionally override the default implementation of mapPropertyName.

Although to be honest, I'm not a fan of writing writing logic in strings. I much prefer creating to separate models, a JSON model and a domain model, where the actual mapping is done in compile-time checked Swift code. So I don't think I would ever use "mapPropertyName", but it is something you could provide using extensions on protocols.