Yes, in general, I think Codable is a poor solution for json decoding just like
I never used NSCoding to convert JSON to and from objects. It feels clumsy.
I found it a much better solution to add a category to NSObject that had
-(NSData*)toJSONRepresentationWithMappings:(NSDictionary*)d
+()fromJSONRepresentation:(NSData*) mappings:(NSDictionary*)d
where mappings might be { @"firstName": @"first_name", etc.... }
and was simple to write a general solution using introspection and KVC.
Codable is a limited one trick pony that would be trivial to write as a trait
or extension if Swift provided the more profound thing - introspection and
reflection. A whole world of opportunities would open up with that and we
could stop wasting time on Codable and KeyPath - neither of which is that
useful when working with string data from the wild.
Please stop messing about with these lil special cases and provide a general
introspection and reflection capability. Until Swift has that, I might as well
use C++.
> On Oct 19, 2017, at 2:03 AM, Morten Bek Ditlevsen via swift-evolution
> <[email protected]> wrote:
>
> Hi all,
> At work we have just added Codable support for a whole bunch of model objects
> in our code base.
> Many places we have added CodingKeys enumeration in order to convert the
> camel cased property names to snake case for our JSON keys.
> As an experiment I have tried adding a KeyCodingStrategy option to a copy of
> the JSONEncoder and JSONDecoder implementations.
> This is currently an enumeration with the following values
> .original
> .snakeCase
> .custom((String) -> String)
>
> I just extended CodingKey as follows:
> extension CodingKey {
> func stringValue(with encodingStrategy:
> StructuralEncoder.KeyEncodingStrategy) -> String {
> switch encodingStrategy {
> case .original:
> return stringValue
> case .snakeCase:
> let pattern = "([a-z0-9])([A-Z])"
> let regex = try! NSRegularExpression(pattern: pattern, options:
> [])
> let range = NSRange(location: 0, length:
> stringValue.characters.count)
> return regex.stringByReplacingMatches(in: stringValue, options:
> [], range: range, withTemplate: "$1_$2").lowercased()
> case .custom(let t):
> return t(stringValue)
> }
> }
> }
>
> and then I replaced all references to key.stringValue with
> key.stringValue(with: self.encoder.options.keyCodingStrategy)
>
> This seems to work very nicely.
>
> So my question is: Do anyone else see the benefit of such an addition to the
> JSONEncoder and JSONDecoder?
>
> The downside as I see it, is that the current CodingKeys are guaranteed to be
> unique by the compiler, and it would be possible to create collisions by
> using key name transforms.
> Is this downside bigger than the gains?
>
> One advantage is that one could argue that one CodingKey strategy may not fit
> all serialization mechanisms. For instance one might wish to have upper camel
> cased keys in Plists (just an example) and snake case in JSON. This method
> could easily support this, while the current CodingKeys strategy cannot...
>
> Looking forward to hearing feedback.
>
> Sincerely,
> /morten
>
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution