<div dir="ltr">How exactly does that work from the perspective of the initializer if you have 2 sets of keys to choose from? Would I extend the initializer to include my feature flag `<span style="font-size:12.8px">public init(from decoder: Decoder, flag: Bool) throws` and switch on that? Or could I pass in the Container I want to use somehow, which seems cleaner to me as an abstraction? </span><span style="font-size:12.8px">(This is similar to what we're already doing with the setup we have.) How does a key jump multiple levels "</span><span style="font-size:12.8px">permissions.can_send_message" and is there a way to know ahead of time which key maps to what property? Needing to express every possible mapping from the initializer seems clumsy to me and I think would fit better as a part of the Container itself.</span></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Apr 10, 2017 at 3:13 PM, Tony Parker <span dir="ltr"><<a href="mailto:anthony.parker@apple.com" target="_blank">anthony.parker@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space">Hi Rex,<div><br><div><div><div class="h5"><blockquote type="cite"><div>On Apr 10, 2017, at 12:48 PM, Rex Fenley via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:</div><br class="m_3559923070299827438Apple-interchange-newline"><div><div dir="ltr"><div>Forgive me if I'm missing something, this is a very large proposal and a lot to parse through. I like how everything is designed as far as I can tell except I'm not sure from this proposal how one would compose multiple different types of Decoders against the same output type. For example, with Location we have.</div><div><br></div><div>// Continuing examples from before; below is automatically generated by the compiler if no customization is needed.</div><div>public struct Location : Codable {</div><div><span class="m_3559923070299827438gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>private enum CodingKeys : CodingKey {</div><div> case latitude</div><div> case longitude</div><div> }</div><div><br></div><div> public init(from decoder: Decoder) throws {</div><div> let container = try decoder.container(keyedBy: CodingKeys.self)</div><div> latitude = try container.decode(Double.self, forKey: .latitude)</div><div> longitude = try container.decode(Double.self, forKey: .longitude)</div><div> }</div><div>}</div><div><br></div><div>However, this initializer seems strictly tied to the `CodingKeys` set of coding keys. From what it appears, if this was used to decode from JSON the format would have to always be:</div><div><br></div><div>{</div><div><span class="m_3559923070299827438gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>"latitude" : 20.0</div><div><span class="m_3559923070299827438gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>"longitude" : 20.0</div><div>}</div><div><br></div><div>I have a use case we're on my client we began the process of switching from one version of an API to another. In one version we had a payload similar to</div><div><br></div><div>{</div><div><span class="m_3559923070299827438gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>"user" : {</div><div><span class="m_3559923070299827438gmail-Apple-tab-span" style="white-space:pre-wrap">                </span>"uuid" : "uuid string..."</div><div><span class="m_3559923070299827438gmail-Apple-tab-span" style="white-space:pre-wrap">                </span>"can_send_message" : true</div><div><span class="m_3559923070299827438gmail-Apple-tab-span" style="white-space:pre-wrap">                </span>"can_delete_message" : false</div><div><span class="m_3559923070299827438gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>}</div><div>}</div><div><br></div><div>this would result in the following Codable (from "user") from what I'm following</div><div><br></div><div>public struct User : Codable {</div><div><span class="m_3559923070299827438gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>private enum CodingKeys : CodingKey {</div><div> case uuid</div><div> case can_send_message</div><div> case can_delete_message</div><div> }</div><div><br></div><div> public init(from decoder: Decoder) throws {</div><div> let container = try decoder.container(keyedBy: CodingKeys.self)</div><div> uuid = try container.decode(Double.self, forKey: .uuid)</div><div> canSendMessage = try container.decode(Bool.self, forKey: .can_send_message)</div><div> canDeleteMessage = try container.decode(Bool.self, forKey: .can_delete_message)</div><div> }</div><div>}</div><div><br></div><div>when we began switching over to the new api the payload was returned as</div><div><br></div><div>{</div><div><span class="m_3559923070299827438gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>user {</div><div><span class="m_3559923070299827438gmail-Apple-tab-span" style="white-space:pre-wrap">                </span>"uuid" : "uuid string..."</div><div><span class="m_3559923070299827438gmail-Apple-tab-span" style="white-space:pre-wrap">                </span>"permissions" : {</div><div><span class="m_3559923070299827438gmail-Apple-tab-span" style="white-space:pre-wrap">                        </span>"can_send_message" : true</div><div><span class="m_3559923070299827438gmail-Apple-tab-span" style="white-space:pre-wrap">                        </span>"can_delete_message" : false</div><div><span class="m_3559923070299827438gmail-Apple-tab-span" style="white-space:pre-wrap">                </span>}</div><div><span class="m_3559923070299827438gmail-Apple-tab-span" style="white-space:pre-wrap">        </span>}</div><div>}</div><div><br></div><div>Here with "permissions" we have a new internal container with a separate set of coding keys. Issue is in my use case I still need to maintain a way to decode the old version simultaneously; we guard all new changes behind feature flags in case something goes awry and we need to roll back our changes.</div><div><br></div><div>How would one go about expressing this new Decoding and the previous Decoding simultaneously on the same User type?</div></div></div></blockquote><div><br></div></div></div>You would fall out of the automatically-generated scenario here, but this use case is exactly what the ‘container’ API is for. You can create a container with a new set of keys, then decode from it.</div><div><br></div><div>Another approach would be to create a nested type that conforms with Codable which represents the “permissions” as a type of its own.</div><div><br></div><div>- Tony</div><div><br><blockquote type="cite"><div><span class=""><div dir="ltr"><div><br></div><div><br></div>-- <br><div class="m_3559923070299827438gmail_signature"><div dir="ltr"><span><div style="line-height:1.15;margin-top:0pt;margin-bottom:0pt"><span style="font-size:16px;font-family:arial;background-color:transparent;font-style:italic;vertical-align:baseline;white-space:pre-wrap">Rex Fenley</span><span style="font-size:16px;font-family:arial;background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> </span><span style="font-size:11px;font-family:arial;color:rgb(153,153,153);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">|</span><span style="line-height:1.15;font-family:arial;color:rgb(153,153,153);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> </span><span style="font-size:11px;font-family:arial;color:rgb(153,153,153);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">IOS DEVELOPER</span><br></div></span><span><br><div style="line-height:1.15;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11px;font-family:arial;color:rgb(153,153,153);vertical-align:baseline;white-space:pre-wrap;background-color:transparent"><img src="https://lh5.googleusercontent.com/xMgzw3JkFL3DLkdwyq0WxJzKs_XP57gVVCaBMvgi1FKCjSeue0xdx3JZeCWBlxN4KRHhHOfdvJbc1N-AjTwXcKIq4cjJg9H7iaFpQ8WbO4N3c9Y5dzi19cPOs_owPquuqw" width="250px;" height="53px;" style="border:none"></span></div><div style="line-height:1.15;margin-top:0pt;margin-bottom:0pt"><a href="https://www.remind.com/" style="text-decoration:none" target="_blank"><span style="font-size:11px;font-family:arial;color:rgb(17,85,204);font-weight:bold;text-decoration:underline;vertical-align:baseline;white-space:pre-wrap;background-color:transparent">Remind.com</span></a><span style="font-family:arial;vertical-align:baseline;white-space:pre-wrap;background-color:transparent"> </span><span style="font-size:11px;font-family:arial;vertical-align:baseline;white-space:pre-wrap;background-color:transparent">| </span><a href="http://blog.remind.com/" style="text-decoration:none" target="_blank"><span style="font-size:11px;font-family:arial;color:rgb(17,85,204);text-decoration:underline;vertical-align:baseline;white-space:pre-wrap;background-color:transparent">BLOG</span></a><span style="font-size:11px;font-family:arial;vertical-align:baseline;white-space:pre-wrap;background-color:transparent"> | </span><a href="https://twitter.com/remindhq" style="text-decoration:none" target="_blank"><span style="font-size:11px;font-family:arial;color:rgb(17,85,204);text-decoration:underline;vertical-align:baseline;white-space:pre-wrap;background-color:transparent">FOLLOW US</span></a><span style="font-size:11px;font-family:arial;vertical-align:baseline;white-space:pre-wrap;background-color:transparent"> | </span><span style="font-family:arial;vertical-align:baseline;white-space:pre-wrap;background-color:transparent"> </span><span style="text-decoration:underline;font-size:11px;font-family:arial;color:rgb(17,85,204);vertical-align:baseline;white-space:pre-wrap;background-color:transparent"><a href="https://www.facebook.com/remindhq" style="text-decoration:none" target="_blank">LIKE US</a></span></div></span></div></div>
</div></span>
______________________________<wbr>_________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br></div></blockquote></div><br></div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><span><p dir="ltr" style="line-height:1.15;margin-top:0pt;margin-bottom:0pt"><span style="font-size:16px;font-family:Arial;background-color:transparent;font-style:italic;vertical-align:baseline;white-space:pre-wrap">Rex Fenley</span><span style="font-size:16px;font-family:Arial;background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> </span><span style="font-size:11px;font-family:Arial;color:rgb(153,153,153);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">|</span><span style="line-height:1.15;font-family:Arial;color:rgb(153,153,153);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"> </span><span style="font-size:11px;font-family:Arial;color:rgb(153,153,153);background-color:transparent;vertical-align:baseline;white-space:pre-wrap">IOS DEVELOPER</span><br></p></span><span><br><p dir="ltr" style="line-height:1.15;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11px;font-family:Arial;color:rgb(153,153,153);vertical-align:baseline;white-space:pre-wrap;background-color:transparent"><img src="https://lh5.googleusercontent.com/xMgzw3JkFL3DLkdwyq0WxJzKs_XP57gVVCaBMvgi1FKCjSeue0xdx3JZeCWBlxN4KRHhHOfdvJbc1N-AjTwXcKIq4cjJg9H7iaFpQ8WbO4N3c9Y5dzi19cPOs_owPquuqw" width="250px;" height="53px;" style="border:none"></span></p><p dir="ltr" style="line-height:1.15;margin-top:0pt;margin-bottom:0pt"><a href="https://www.remind.com/" style="text-decoration:none" target="_blank"><span style="font-size:11px;font-family:Arial;color:rgb(17,85,204);font-weight:bold;text-decoration:underline;vertical-align:baseline;white-space:pre-wrap;background-color:transparent">Remind.com</span></a><span style="font-family:Arial;vertical-align:baseline;white-space:pre-wrap;background-color:transparent"> </span><span style="font-size:11px;font-family:Arial;vertical-align:baseline;white-space:pre-wrap;background-color:transparent">| </span><a href="http://blog.remind.com/" style="text-decoration:none" target="_blank"><span style="font-size:11px;font-family:Arial;color:rgb(17,85,204);text-decoration:underline;vertical-align:baseline;white-space:pre-wrap;background-color:transparent">BLOG</span></a><span style="font-size:11px;font-family:Arial;vertical-align:baseline;white-space:pre-wrap;background-color:transparent"> | </span><a href="https://twitter.com/remindhq" style="text-decoration:none" target="_blank"><span style="font-size:11px;font-family:Arial;color:rgb(17,85,204);text-decoration:underline;vertical-align:baseline;white-space:pre-wrap;background-color:transparent">FOLLOW US</span></a><span style="font-size:11px;font-family:Arial;vertical-align:baseline;white-space:pre-wrap;background-color:transparent"> | </span><span style="font-family:Arial;vertical-align:baseline;white-space:pre-wrap;background-color:transparent"> </span><span style="text-decoration:underline;font-size:11px;font-family:Arial;color:rgb(17,85,204);vertical-align:baseline;white-space:pre-wrap;background-color:transparent"><a href="https://www.facebook.com/remindhq" style="text-decoration:none" target="_blank">LIKE US</a></span></p></span></div></div>
</div>