<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/xhtml; charset=utf-8">
</head>
<body>
<div style="font-family:sans-serif"><div style="white-space:normal">
<p dir="auto">If you need multiple different representations for multiple different formats, then yes, you will likely want to supply different <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7">CodingKeys</code> enums for those formats and write a custom encode which switches on the format you're writing to. Or, you can use one <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7">CodingKeys</code> enum which has multiple different key representations (for the different formats you want to support) and use that.</p>
<p dir="auto">Automatic key renaming is an inherently unsafe operation, so it's not something that we want to provide out of the box, or encourage, but it should be possible if you really want it.</p>
<p dir="auto">On 1 May 2017, at 13:04, Anders Ha wrote:</p>
<p dir="auto"></p></div>
<div style="white-space:normal"><blockquote style="border-left:2px solid #777; color:#777; margin:0 0 5px; padding-left:5px"><p dir="auto">I do mean optional automatic translation on the encoders’ and decoders’ end though. Derived conformances from other common naming conventions are nice to have, but does not help if one wants to define a model that can be decoded from and encoded into different coded representations of itself. It also “hardwired" the model with a specific coding scheme, which does not seem very nice from an encapsulation PoV.<br>
<br>
That said I am fairly sure there would be third party libraries providing key mapping/transformation, if Foundation’s encoders and decoders do not provide such functionality. So it is probably not a big deal.<br>
<br>
Regards<br>
Anders<br>
</p>
<blockquote style="border-left:2px solid #777; color:#999; margin:0 0 5px; padding-left:5px; border-left-color:#999"><p dir="auto">On 2 May 2017, at 3:06 AM, Itai Ferber <iferber@apple.com> wrote:<br>
<br>
Sorry, one clarifying statement: it's not the JSON encoder and decoder that will be providing this renaming (since they should be encoding the key values they are given as-is); the key names are part of the definition of the enum, as declared as part of the type.<br>
<br>
On 1 May 2017, at 12:04, Itai Ferber via swift-evolution wrote:<br>
<br>
Yes, this should be true for most types.<br>
The compiler derives conformance based on a nested CodingKeys type within your Codable type. If you do not supply one, it will derive one on your behalf, but if you do provide one, making a naming transition like this is trivial:<br>
<br>
public struct Post<br>
: Codable {<br>
<br>
let authorID: Int<br>
<br>
<br>
let authorName: String<br>
<br>
<br>
let bodyText: String<br>
<br>
<br>
<br>
private enum CodingKeys: String<br>
, CodingKey {<br>
<br>
case authorID = "author_id"<br>
<br>
<br>
case authorName = "author_name"<br>
<br>
<br>
case bodyText = "body_text"<br>
<br>
}<br>
<br>
<br>
// init(from:) and encode(to:) are still automatically generated<br>
<br>
}<br>
<br>
This is something we wanted to explicitly support as we don't want users to have to violate Swift naming guidelines, and is a step along the progressive disclosure of the API that we want to provide.<br>
As long as the case names of the enum match 1-to-1 with property names, derived conformance still applies.<br>
<br>
On 1 May 2017, at 11:39, Anders Ha wrote:<br>
<br>
<br>
I thought it would be quite trivial to have the JSON encoder and decoder transforming the keys between camel case and snake case, wouldn't it?<br>
<br>
<br>
Regards<br>
Anders<br>
</p>
<blockquote style="border-left:2px solid #777; color:#BBB; margin:0 0 5px; padding-left:5px; border-left-color:#BBB"><p dir="auto">On 2 May 2017, at 1:57 AM, Jon Shier via swift-evolution <swift-evolution@swift.org> wrote:<br>
<br>
        FYI, I’d give the derived implementations a very low chance of ever being used for JSON. Unless developers violate the Swift naming guidelines for their properties at least or they don’t have properties with multiword keys.<br>
        Once this functionality has landed for the Swift 4 branch, I plan to implement some of the tricky JSON types I had to decode on a recent project, just to see how painful the custom syntax will be, and to compare it to my existing Argo implementation. Hopefully there will be time for at least one round of feedback to be integrated into this functionality.<br>
<br>
<br>
<br>
Jon<br>
<br>
</p>
<blockquote style="border-left:2px solid #777; color:#BBB; margin:0 0 5px; padding-left:5px; border-left-color:#BBB"><p dir="auto">On May 1, 2017, at 12:54 PM, Itai Ferber via swift-evolution <swift-evolution@swift.org> wrote:<br>
<br>
Hi Goffredo,<br>
</p>
<blockquote style="border-left:2px solid #777; color:#BBB; margin:0 0 5px; padding-left:5px; border-left-color:#BBB"><p dir="auto">On Apr 26, 2017, at 2:00 PM, Goffredo Marocchi <panajev@gmail.com> wrote:<br>
<br>
Hello Itai,<br>
<br>
Sorry for the confusion, but I understood that the following<br>
</p>
<blockquote style="border-left:2px solid #777; color:#BBB; margin:0 0 5px; padding-left:5px; border-left-color:#BBB"><p dir="auto">To answer your second question, the reason is that using the protocol implies that all encoders and decoders must support anything that conforms to that protocol. We’re not sure this is a reasonable requirement. Many formats do not have any kind of support for arbitrary size integers, for example. Therefore, we felt it was best to limit it to a set of concrete types.</p>
</blockquote><p dir="auto">meant it would actually hinder that kind of transformation or make it more difficult to write custom decoders and encoders. Sorry if I misunderstood that.<br>
<br>
One follow up question: what would happen if inside the JSON mock object you posted I were to remove the 'address' key (in terms of the produced object and how to access its inner properties)?<br>
<br>
What would happen if I remove the 'name' one or better if I add another key to the JSON object?</p>
</blockquote><p dir="auto">Codable conformance is derived by default to require that all non-optional properties be initialized. This means that if you have a non-optional property address: Address but there is no address key in the JSON payload you're decoding from, it will throw an error to indicate that the key was not found.<br>
On the flip side, if the JSON payload has information in it which your type does not have (e.g. if there is an address in the JSON, but your Person just has name), the extra data is ignored.<br>
<br>
This, however, is just in the default, derived conformance. For more complex cases, you can always provide your own init(from:) and encode(to:)to do custom decoding. If you have a property which may or may not be in the JSON, you can always decodeIfPresent, which will return nil if the key or value was not found.<br>
If you need to access sub-objects in the JSON data which do not map to your properties 1-to-1, e.g. your payload looks like {"name": "John Doe", "address": { "street": "1 Infinite Loop", ... } }, but your type looks like<br>
struct Person {<br>
<br>
<br>
let name: String<br>
<br>
<br>
let street: String<br>
<br>
<br>
let city: String<br>
<br>
<br>
// ...<br>
}<br>
then you can always access the nested data by requesting a nestedContainer(keyedBy: ..., forKey: .address) which will return a container wrapping the address sub-object, which you can then pull fields out of.<br>
<br>
The derived conformance case gives a reasonable default, but you can always write your own init(from:) and encode(to:) to handle custom needs.<br>
</p>
<blockquote style="border-left:2px solid #777; color:#BBB; margin:0 0 5px; padding-left:5px; border-left-color:#BBB"><p dir="auto">Sent from my iPhone<br>
<br>
On 26 Apr 2017, at 21:28, Itai Ferber <iferber@apple.com> wrote:<br>
</p>
<blockquote style="border-left:2px solid #777; color:#BBB; margin:0 0 5px; padding-left:5px; border-left-color:#BBB"><p dir="auto">Hi Goffredo,<br>
<br>
Unless I'm misunderstanding what you mean here, this is exactly what we're proposing with the API — anything Encodable can encode any type that is Encodable as a nested value:<br>
<br>
struct Person<br>
: Codable {<br>
<br>
let name: String<br>
<br>
<br>
let address<br>
: Address<br>
}<br>
<br>
<br>
struct Address<br>
: Codable {<br>
<br>
let street: String<br>
<br>
<br>
let city: String<br>
<br>
<br>
let state: String<br>
<br>
<br>
let zipCode: Int<br>
<br>
<br>
let country: String<br>
<br>
}<br>
<br>
<br>
let address = Address(street: "1 Infinite Loop", city: "Cupertino", state: "CA", zipCode: 95014, country: "United States"<br>
)<br>
<br>
let person = Person(name: "John Doe"<br>
, address: address)<br>
<br>
<br>
let encoder<br>
= JSONEncoder()<br>
<br>
let payload<br>
= try encoder.encode(person)<br>
<br>
print(String(data: payload, encoding: .utf8)!) // => {"name": "John Doe", address: {"street": "1 Infinite Loop", ... } }<br>
<br>
<br>
<br>
let decoder<br>
= JSONDecoder()<br>
<br>
let decoded = try decoder.decode(Person.self, from: payload) // => Person(name: "John Doe", address: ...)<br>
Or have I misunderstood you?<br>
<br>
— Itai<br>
<br>
On 26 Apr 2017, at 13:11, Goffredo Marocchi via swift-evolution wrote:<br>
<br>
<br>
<br>
<br>
Sent from my iPhone<br>
<br>
On 26 Apr 2017, at 17:24, Tony Parker via swift-evolution <swift-evolution@swift.org> wrote:<br>
</p>
<blockquote style="border-left:2px solid #777; color:#BBB; margin:0 0 5px; padding-left:5px; border-left-color:#BBB"><p dir="auto">Hi Riley,<br>
</p>
<blockquote style="border-left:2px solid #777; color:#BBB; margin:0 0 5px; padding-left:5px; border-left-color:#BBB"><p dir="auto">On Apr 25, 2017, at 6:11 PM, Riley Testut via swift-evolution <swift-evolution@swift.org> wrote:<br>
<br>
I’m sure this has already been discussed, but why are the methods throwing NSErrors and not Enums? If I’m remembering correctly, the original reason for this was because this was meant to be a part of Foundation. Now that this is in the Standard Library, however, it seems strange that we’re still using NSError.<br>
<br>
Second question that again I’m sure was asked and answered already, but: why do we require implementations for each concrete numeric type (Int, Int8, Int16, Float, etc), instead of using protocols (such as the new Integer protocols)?</p>
</blockquote><p dir="auto">To answer your second question, the reason is that using the protocol implies that all encoders and decoders must support anything that conforms to that protocol.</p>
</blockquote><p dir="auto">Would this make it easier to transform nested JSON into a nested object/struct? If so it could be useful, very useful.<br>
</p>
<blockquote style="border-left:2px solid #777; color:#BBB; margin:0 0 5px; padding-left:5px; border-left-color:#BBB"><p dir="auto">We’re not sure this is a reasonable requirement. Many formats do not have any kind of support for arbitrary size integers, for example. Therefore, we felt it was best to limit it to a set of concrete types.<br>
</p>
</blockquote><p dir="auto">I honk we would be missing a trick, unless I am missing something here, that was very powerful in libraries like Mantle for iOS: the ability to translate a nested JSON object (some keys in the JSON object having a JSON object as value, etc...) in an MTLModel subclass composed of other MTLModel subclasses where doing the transformation of the root object would call the right model needed to transform for the child JSON objects.<br>
Working with Mantle is safe, rugged (it does not cause crashes if the JSON file changes), and allows you to break the problem into chunks and present a coherent simple view to the code that makes use of the instance you created out of the JSON input. Reference: <a href="https://github.com/Mantle/Mantle/blob/master/README.md" style="color:#BBB">https://github.com/Mantle/Mantle/blob/master/README.md</a><br>
<br>
</p>
<blockquote style="border-left:2px solid #777; color:#BBB; margin:0 0 5px; padding-left:5px; border-left-color:#BBB"><p dir="auto">We could change our minds on this before we ship Swift 4, if we feel it was the wrong decision. Now that the proposals are accepted we will be landing these branches in master soon, which means everyone has a great chance to try it out and see how it feels in real world usage before it’s final.<br>
<br>
- Tony<br>
</p>
<blockquote style="border-left:2px solid #777; color:#BBB; margin:0 0 5px; padding-left:5px; border-left-color:#BBB"><blockquote style="border-left:2px solid #777; color:#BBB; margin:0 0 5px; padding-left:5px; border-left-color:#BBB"><p dir="auto">On Apr 25, 2017, at 3:59 PM, Douglas Gregor via swift-evolution <swift-evolution@swift.org> wrote:<br>
<br>
Proposal Link: <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0166-swift-archival-serialization.md" style="color:#BBB">https://github.com/apple/swift-evolution/blob/master/proposals/0166-swift-archival-serialization.md</a><br>
<br>
Hello Swift Community,<br>
<br>
The review of SE-0166 “Swift Archival & Serialization” ran from April 6...12, 2017. The proposal is accepted with some minor modifications. Specifically, the core protocols and types will be sunk down into the Swift standard library for more tight integration with the Swift language and compiler, and the operations specifically involving Foundation’s “Data” type will be removed. The proposal document has been updated with more detail. Thank you everyone for participating in this review!<br>
<br>
        - Doug<br>
        Review Manager<br>
<br>
_______________________________________________<br>
swift-evolution mailing list<br>
swift-evolution@swift.org<br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="color:#BBB">https://lists.swift.org/mailman/listinfo/swift-evolution</a></p>
</blockquote><p dir="auto">_______________________________________________<br>
swift-evolution mailing list<br>
swift-evolution@swift.org<br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="color:#BBB">https://lists.swift.org/mailman/listinfo/swift-evolution</a></p>
</blockquote><p dir="auto">_______________________________________________<br>
swift-evolution mailing list<br>
swift-evolution@swift.org<br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="color:#BBB">https://lists.swift.org/mailman/listinfo/swift-evolution</a></p>
</blockquote><p dir="auto">_______________________________________________<br>
swift-evolution mailing list<br>
swift-evolution@swift.org<br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="color:#BBB">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</p>
</blockquote></blockquote><p dir="auto">_______________________________________________<br>
swift-evolution mailing list<br>
swift-evolution@swift.org<br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="color:#BBB">https://lists.swift.org/mailman/listinfo/swift-evolution</a></p>
</blockquote><p dir="auto">_______________________________________________<br>
swift-evolution mailing list<br>
swift-evolution@swift.org<br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="color:#BBB">https://lists.swift.org/mailman/listinfo/swift-evolution</a></p>
</blockquote><p dir="auto">_______________________________________________<br>
swift-evolution mailing list<br>
swift-evolution@swift.org<br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="color:#999">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</p>
</blockquote></blockquote></div>
<div style="white-space:normal">
</div>
</div>
</body>
</html>