<html><body bgcolor="#FFFFFF"><p><font size="2">Brandon<br><br>I cooked up a simple example and it works as expected.<br><br></font><font face="Monaco">ylin@youming-mbpr:~/Swift/Configuration$ swift</font><br><font face="Monaco">Welcome to Apple Swift version 4.0-dev (LLVM 2dedb62a0b, Clang b9d76a314c, Swift 0899bd328a). Type :help for assistance.</font><br><font face="Monaco">  1&gt; </font><font face="Monaco">import Foundation</font><br><font face="Monaco">  2&gt; </font><font face="Monaco">struct A: Codable { </font><br><font face="Monaco">  3. </font><font face="Monaco">    var integer: Int </font><br><font face="Monaco">  4. </font><font face="Monaco"> </font><br><font face="Monaco">  5. </font><font face="Monaco">    public init(integer: Int) { </font><br><font face="Monaco">  6. </font><font face="Monaco">        self.integer = integer </font><br><font face="Monaco">  7. </font><font face="Monaco">    } </font><br><font face="Monaco">  8. </font><font face="Monaco"> </font><br><font face="Monaco">  9. </font><font face="Monaco">    public init(from decoder: Decoder) throws { </font><br><font face="Monaco"> 10. </font><font face="Monaco">        print(&quot;Custom decoder&quot;) </font><br><font face="Monaco"> 11. </font><font face="Monaco">        let container = try decoder.container(keyedBy: CodingKeys.self) </font><br><font face="Monaco"> 12. </font><font face="Monaco">        integer = try container.decode(Int.self, forKey: .integer) </font><br><font face="Monaco"> 13. </font><font face="Monaco">    } </font><br><font face="Monaco"> 14. </font><font face="Monaco">} </font><br><font face="Monaco"> 15. </font><font face="Monaco"> </font><br><font face="Monaco"> 16. </font><font face="Monaco">try! JSONDecoder().decode(A.self, from: JSONEncoder().encode(A(integer: 42)))</font><br><font face="Monaco">Custom decoder</font><br><font face="Monaco">$R0: A = {</font><br><font face="Monaco">  integer = 42</font><br><font face="Monaco">}</font><font size="2"><br></font><br><font size="2">You should be able to implement your custom init to convert the number into a string and JSONDecoder should use that automatically.<br></font><br><font size="2">Thanks,<br><br>Youming Lin<br>IBM Cloud, Swift@IBM, Kitura developer<br>Austin, TX<br>GitHub: @youming-lin</font><br><br><img width="16" height="16" src="cid:1__=8FBB0B1FDFE583068f9e8a93df938690918c8FB@" border="0" alt="Inactive hide details for &quot;Sneed, Brandon&quot; ---08/30/2017 04:14:57 PM---Thanks Youming, Ok, thanks!  I did try that, but I can’"><font size="2" color="#424282">&quot;Sneed, Brandon&quot; ---08/30/2017 04:14:57 PM---Thanks Youming, Ok, thanks!  I did try that, but I can’t seem to figure out how to make it actually</font><br><br><font size="2" color="#5F5F5F">From:        </font><font size="2">&quot;Sneed, Brandon&quot; &lt;brsneed@ebay.com&gt;</font><br><font size="2" color="#5F5F5F">To:        </font><font size="2">Youming Lin &lt;ylin@us.ibm.com&gt;</font><br><font size="2" color="#5F5F5F">Cc:        </font><font size="2">Tony Parker &lt;anthony.parker@apple.com&gt;, &quot;swift-corelibs-dev@swift.org&quot; &lt;swift-corelibs-dev@swift.org&gt;, &quot;swift-corelibs-dev-bounces@swift.org&quot; &lt;swift-corelibs-dev-bounces@swift.org&gt;</font><br><font size="2" color="#5F5F5F">Date:        </font><font size="2">08/30/2017 04:14 PM</font><br><font size="2" color="#5F5F5F">Subject:        </font><font size="2">Re: [swift-corelibs-dev] Adding type conversion capabilities to JSON encode/decode</font><br><hr width="100%" size="2" align="left" noshade style="color:#8091A5; "><br><br><br>Thanks Youming,<br> <br>Ok, thanks!  I did try that, but I can’t seem to figure out how to make it actually get used in the decoding process.  That being my preferred way, I tried it first.  I chalked it not working up to Swift not knowing which of the 2 init(from decoder:) functions to call, mine or theirs.  But, maybe there’s something I’m missing here.<br> <br>Any insight is appreciated.<br> <br>Thanks!<br> <br> <br> <br>Brandon Sneed<br> <br><b>From: </b>Youming Lin &lt;ylin@us.ibm.com&gt;<b><br>Date: </b>Wednesday, August 30, 2017 at 1:18 PM<b><br>To: </b>&quot;Sneed, Brandon&quot; &lt;brsneed@ebay.com&gt;<b><br>Cc: </b>Tony Parker &lt;anthony.parker@apple.com&gt;, &quot;swift-corelibs-dev@swift.org&quot; &lt;swift-corelibs-dev@swift.org&gt;, &quot;swift-corelibs-dev-bounces@swift.org&quot; &lt;swift-corelibs-dev-bounces@swift.org&gt;<b><br>Subject: </b>Re: [swift-corelibs-dev] Adding type conversion capabilities to JSON encode/decode<br><font face="Times New Roman"> </font><p><font size="2" face="Times New Roman">Brandon<br><br>&gt;</font><font face="Times New Roman">JSON’s types effectively end up matching specifically to primitives, of which there is no mechanism to override the behavior of how a String gets decoded for instance.</font><font size="2" face="Times New Roman"><br><br>You can override the default behavior with your own custom init(from:) implementation for your Codable struct: </font><a href="https://urldefense.proofpoint.com/v2/url?u=https-3A__na01.safelinks.protection.outlook.com_-3Furl-3Dhttps-253A-252F-252Fdeveloper.apple.com-252Fdocumentation-252Fswift-252Fdecodable-252F2894081-2Dinit-26data-3D02-257C01-257Cbrsneed-2540ebay.com-257C6290a819253b47b0eb2408d4efe454ae-257C46326bff992841a0baca17c16c94ea99-257C0-257C0-257C636397211330551372-26sdata-3DoLr1Q10-252BztzwG-252BCXpMinBzJNTwSy-252FjoBsKm9Glg1-252FxY-253D-26reserved-3D0&d=DwMGaQ&c=jf_iaSHvJObTbx-siA1ZOg&r=gkRZBtsmKeGPCOlAIRJoOA&m=c3lYikOfd2-4q_nd_qMnJ4gXKIuKuxxoJRxIrIZc3Hw&s=h1azblXptqRwHqDQhejN9sSFa8dR-Gd8OkB7_6VwgNg&e="><u><font size="2" color="#0000FF" face="Times New Roman">https://developer.apple.com/documentation/swift/decodable/2894081-init</font></u></a><font size="2" face="Times New Roman"><br><br>You can check Foundation source code (i.e., the URL struct) on how this can be implemented.</font><font face="Times New Roman"><br></font><font size="2" face="Times New Roman"><br>Thanks,<br><br>Youming Lin<br>IBM Cloud, Swift@IBM, Kitura developer<br>Austin, TX<br>GitHub: @youming-lin</font><font face="Times New Roman"><br><br></font><img src="cid:2__=8FBB0B1FDFE583068f9e8a93df938690918c8FB@" width="16" height="16" alt="nactive hide details for &quot;Sneed, Brandon via swift-corelibs-dev&quot; ---08/30"><font size="2" color="#424282" face="Times New Roman">&quot;Sneed, Brandon via swift-corelibs-dev&quot; ---08/30/2017 03:07:05 PM---Hi Tony, I like the idea that the type itself is responsible for the conversion. My own json encode</font><font face="Times New Roman"><br></font><font size="2" color="#5F5F5F" face="Times New Roman"><br>From: </font><font size="2" face="Times New Roman">&quot;Sneed, Brandon via swift-corelibs-dev&quot; &lt;swift-corelibs-dev@swift.org&gt;</font><font size="2" color="#5F5F5F" face="Times New Roman"><br>To: </font><font size="2" face="Times New Roman">Tony Parker &lt;anthony.parker@apple.com&gt;</font><font size="2" color="#5F5F5F" face="Times New Roman"><br>Cc: </font><font size="2" face="Times New Roman">&quot;swift-corelibs-dev@swift.org&quot; &lt;swift-corelibs-dev@swift.org&gt;</font><font size="2" color="#5F5F5F" face="Times New Roman"><br>Date: </font><font size="2" face="Times New Roman">08/30/2017 03:07 PM</font><font size="2" color="#5F5F5F" face="Times New Roman"><br>Subject: </font><font size="2" face="Times New Roman">Re: [swift-corelibs-dev] Adding type conversion capabilities to JSON encode/decode</font><font size="2" color="#5F5F5F" face="Times New Roman"><br>Sent by: </font><font size="2" face="Times New Roman">swift-corelibs-dev-bounces@swift.org</font><br><hr width="100%" size="2" align="left" noshade><br><font face="Times New Roman"><br><br><br>Hi Tony,<br><br>I like the idea that the type itself is responsible for the conversion. My own json encode/decode library worked this way and it was really great, however in trying to leverage Swift4 into it, or to replace it, I just don’t see how that’s possible given how it’s currently structured.<br><br>JSON’s types effectively end up matching specifically to primitives, of which there is no mechanism to override the behavior of how a String gets decoded for instance. The only way I can think of to accomplish that is to create *</font><b><font face="Times New Roman">another</font></b><font face="Times New Roman">* type, JSONString for example, but since String is a struct, I can’t subclass it, and instead need to have the real value buried inside of it … it seems to start getting messy very quickly. It also adds the obfuscation of dealing with yet another type, which I’m not against, but just feels less than ideal.<br><br><br>Brandon Sneed<br></font><b><font face="Times New Roman"><br>From: </font></b><font face="Times New Roman">&lt;anthony.parker@apple.com&gt; on behalf of Tony Parker &lt;anthony.parker@apple.com&gt;</font><b><font face="Times New Roman"><br>Date: </font></b><font face="Times New Roman">Wednesday, August 30, 2017 at 11:30 AM</font><b><font face="Times New Roman"><br>To: </font></b><font face="Times New Roman">&quot;Sneed, Brandon&quot; &lt;brsneed@ebay.com&gt;</font><b><font face="Times New Roman"><br>Cc: </font></b><font face="Times New Roman">Itai Ferber &lt;iferber@apple.com&gt;, &quot;swift-corelibs-dev@swift.org&quot; &lt;swift-corelibs-dev@swift.org&gt;</font><b><font face="Times New Roman"><br>Subject: </font></b><font face="Times New Roman">Re: [swift-corelibs-dev] Adding type conversion capabilities to JSON encode/decode<br><br>I’m still not convinced that we should actually provide such a strategy. <br><br>Conversions like those below seem like the domain of each type that is being decoded. If, in a particular type, the “number” can be either a true number or a string, then that type can try decoding it as one or the other and fall back as required. That puts the responsibility of doing that kind of conversion in the type itself.<br><br>JSON has very few types already. I’m not sure we want to blur the line between numbers and strings automatically…<br><br>- Tony</font><ul><ul><ul><ul><font face="Times New Roman">On Aug 30, 2017, at 11:24 AM, Sneed, Brandon via swift-corelibs-dev &lt;</font><a href="mailto:swift-corelibs-dev@swift.org"><u><font color="#0000FF" face="Times New Roman">swift-corelibs-dev@swift.org</font></u></a><font face="Times New Roman">&gt; wrote:<br><br>Hi Itai,<br><br>No problem! Thanks for the heads up. Is there any way I could be involved? Happy to do the work to whatever guidance your team might have. I’m mostly just interested in it being there soon, hence volunteering. <br><br>Thanks!<br><br><br>Brandon Sneed<br></font><b><font face="Times New Roman"><br>From: </font></b><font face="Times New Roman">&lt;</font><a href="mailto:iferber@apple.com"><u><font color="#0000FF" face="Times New Roman">iferber@apple.com</font></u></a><font face="Times New Roman">&gt; on behalf of Itai Ferber &lt;</font><a href="mailto:iferber@apple.com"><u><font color="#0000FF" face="Times New Roman">iferber@apple.com</font></u></a><font face="Times New Roman">&gt;</font><b><font face="Times New Roman"><br>Date: </font></b><font face="Times New Roman">Wednesday, August 30, 2017 at 11:22 AM</font><b><font face="Times New Roman"><br>To: </font></b><font face="Times New Roman">&quot;Sneed, Brandon&quot; &lt;</font><a href="mailto:brsneed@ebay.com"><u><font color="#0000FF" face="Times New Roman">brsneed@ebay.com</font></u></a><font face="Times New Roman">&gt;</font><b><font face="Times New Roman"><br>Cc: </font></b><font face="Times New Roman">&quot;</font><a href="mailto:swift-corelibs-dev@swift.org"><u><font color="#0000FF" face="Times New Roman">swift-corelibs-dev@swift.org</font></u></a><font face="Times New Roman">&quot; &lt;</font><a href="mailto:swift-corelibs-dev@swift.org"><u><font color="#0000FF" face="Times New Roman">swift-corelibs-dev@swift.org</font></u></a><font face="Times New Roman">&gt;</font><b><font face="Times New Roman"><br>Subject: </font></b><font face="Times New Roman">Re: [swift-corelibs-dev] Adding type conversion capabilities to JSON encode/decode<br></font><font face="Helvetica"><br>Hi Brandon,<br>Thanks for looking at this! We’ve got plans internally to potentially add a strategy to </font><font size="2" face="Courier New">JSONEncoder</font><font face="Helvetica">/</font><font size="2" face="Courier New">JSONDecoder</font><font face="Helvetica"> to allow lenient conversions like this — i.e. implicitly stringify numbers (or parse them from string input), among some others.<br>This would be opt-in for consumers of </font><font size="2" face="Courier New">JSONDecoder</font><font face="Helvetica"> while not requiring any special annotations on </font><font size="2" face="Courier New">Codable</font><font face="Helvetica"> types.<br>— Itai<br>On 30 Aug 2017, at 10:59, Sneed, Brandon via swift-corelibs-dev wrote:</font><font color="#777777" face="Times New Roman"><br>Hi everyone,</font><font face="Times New Roman"><br></font><font color="#777777" face="Times New Roman"><br>Just throwing this out to see if anyone else is working on this, or has opinions/suggestions on how it’s implemented. I’d like to add this to the Codable/JSONDecoder/JSONEncoder system if no one else is working on it.</font><font face="Times New Roman"><br></font><font color="#777777" face="Times New Roman"><br>Type type conversion, I mean given this JSON payload:</font><font face="Times New Roman"><br></font><font color="#777777" face="Times New Roman"><br>{<br>&quot;name&quot;: &quot;Endeavor”,<br>&quot;abv&quot;: 8.9,<br>&quot;brewery&quot;: &quot;Saint Arnold”,<br>&quot;style&quot;: &quot;ipa&quot;<br>}</font><font face="Times New Roman"><br></font><font color="#777777" face="Times New Roman"><br>and a struct defined as:</font><font face="Times New Roman"><br></font><font color="#777777" face="Times New Roman"><br>struct Beer: Codable {<br>let name: String<br>let abv: String<br>let brewery: String<br>let style: BeerStyle<br>}</font><font face="Times New Roman"><br></font><font color="#777777" face="Times New Roman"><br>Notice that “abv” is a number in the JSON, but a String in the struct. I’d like to make it such that I can let the system know it’s ok to convert it from a number to a string as opposed to throwing an exception. The benefits are:</font><font face="Times New Roman"><br></font><font color="#777777" face="Times New Roman"><br>1. It’s defensive; service types can change without causing my application to crash.<br>2. It allows a developer to work with the types they want to work with as opposed to what the server provides, thus saving them time of writing a custom encode/decode code for all members.</font><font face="Times New Roman"><br></font><font color="#777777" face="Times New Roman"><br>The argument against it that I’ve heard is generally “it’s a service bug, make them fix it”, which is valid but the reality is we’re not all in control of the services we injest. The same type of logic could be applied to a member name changing, though I haven’t seen this happen often in practice. I do see types in a json payload change with some frequency though. I think much of the reason stems from the fact that type conversion in javascript is effectively free, ie: you ask for a String, you get a String if possible.</font><font face="Times New Roman"><br></font><font color="#777777" face="Times New Roman"><br>To implement this type conversion in practice, looking at it from the point of view using Codable/JSON(en/de)coder, one way would be to make it opt-in:</font><font face="Times New Roman"><br></font><font color="#777777" face="Times New Roman"><br>struct Beer: Codable, CodingConvertible {<br>let name: String<br>let abv: String<br>let brewery: String<br>let style: BeerStyle<br>}</font><font face="Times New Roman"><br></font><font color="#777777" face="Times New Roman"><br>I like this because looking at the struct, the members still remain clear and relatively unambiguous. The downside is it’s unknown which member is likely to get converted. And since it’s opt-in, conversion doesn’t happen if the CodingConvertible conformance isn’t adhered to.</font><font face="Times New Roman"><br></font><font color="#777777" face="Times New Roman"><br>Another option would be to box each type, like so:</font><font face="Times New Roman"><br></font><font color="#777777" face="Times New Roman"><br>struct Beer: Codable {<br>let name: String<br>let abv: Convertible&lt;String&gt;<br>let brewery: String<br>let style: BeerStyle<br>}</font><font face="Times New Roman"><br></font><font color="#777777" face="Times New Roman"><br>This seems tedious for developers, but would show which types are being converted. It does however seriously weaken benefit #1 above.</font><font face="Times New Roman"><br></font><font color="#777777" face="Times New Roman"><br>Those example usages above aside, I do think it’d be best if this conversion behavior was the default and no end-developer changes required. I think that could be done without impact to code that’s been already been written against the JSON en/decode bits.</font><font face="Times New Roman"><br></font><font color="#777777" face="Times New Roman"><br>I’m very open to alternatives, other ideas, or anything else you might have to say on the subject. Thanks for reading!</font><font face="Times New Roman"><br><br><br></font><font color="#777777" face="Times New Roman"><br>Brandon Sneed</font><font face="Times New Roman"><br><br><br><br></font><font color="#777777" face="Helvetica"><br>_______________________________________________<br>swift-corelibs-dev mailing list</font><u><font color="#0000FF" face="Times New Roman"><br></font></u><a href="mailto:swift-corelibs-dev@swift.org"><u><font color="#0000FF" face="Helvetica">swift-corelibs-dev@swift.org</font></u></a><u><font color="#0000FF" face="Times New Roman"><br></font></u><a href="https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Furldefense.proofpoint.com%2Fv2%2Furl%3Fu%3Dhttps-3A__na01.safelinks.protection.outlook.com_-3Furl-3Dhttps-253A-252F-252Flists.swift.org-252Fmailman-252Flistinfo-252Fswift-2Dcorelibs-2Ddev-26data-3D02-257C01-257Cbrsneed-2540ebay.com-257C0e58a975be44418826d608d4efd427dc-257C46326bff992841a0baca17c16c94ea99-257C0-257C0-257C636397141865218008-26sdata-3DytYIqDtMesw4NnpUbFmiWF2-252FKfxlawG4YuVWPJd099Y-253D-26reserved-3D0%26d%3DDwMGaQ%26c%3Djf_iaSHvJObTbx-siA1ZOg%26r%3DgkRZBtsmKeGPCOlAIRJoOA%26m%3DViDSVPImta3StTVAcktby2PMF_-du5itzz47jo-tNHg%26s%3DrVZl8iT3jj1nzuDTCqZ1pkhQIZD3-Byi8PUj50swTUg%26e%3D&data=02%7C01%7Cbrsneed%40ebay.com%7C6290a819253b47b0eb2408d4efe454ae%7C46326bff992841a0baca17c16c94ea99%7C0%7C0%7C636397211330551372&sdata=GkxX7xyhtHr1zqISNmjeBhvOkVoZdOihXcaugXSK9tA%3D&reserved=0"><u><font color="#777777" face="Helvetica">https://lists.swift.org/mailman/listinfo/swift-corelibs-dev</font></u></a><font size="2" face="Helvetica"><br>_______________________________________________<br>swift-corelibs-dev mailing list</font><u><font color="#0000FF" face="Times New Roman"><br></font></u><a href="mailto:swift-corelibs-dev@swift.org"><u><font size="2" color="#0000FF" face="Helvetica">swift-corelibs-dev@swift.org</font></u></a><u><font color="#0000FF" face="Times New Roman"><br></font></u><a href="https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Furldefense.proofpoint.com%2Fv2%2Furl%3Fu%3Dhttps-3A__na01.safelinks.protection.outlook.com_-3Furl-3Dhttps-253A-252F-252Flists.swift.org-252Fmailman-252Flistinfo-252Fswift-2Dcorelibs-2Ddev-26data-3D02-257C01-257Cbrsneed-2540ebay.com-257Cf2eba37a5b40474e09b108d4efd5372d-257C46326bff992841a0baca17c16c94ea99-257C0-257C0-257C636397146413883032-26sdata-3DC1-252F8MXq-252Fh7NHgyxeKDkcHDcigtQjSztCaAeUxBzYZ3g-253D-26reserved-3D0%26d%3DDwMGaQ%26c%3Djf_iaSHvJObTbx-siA1ZOg%26r%3DgkRZBtsmKeGPCOlAIRJoOA%26m%3DViDSVPImta3StTVAcktby2PMF_-du5itzz47jo-tNHg%26s%3DLQ0cgWtC9rXRTDLu0W58VIukWrsRssHsIMGb9U6Y0MU%26e%3D&data=02%7C01%7Cbrsneed%40ebay.com%7C6290a819253b47b0eb2408d4efe454ae%7C46326bff992841a0baca17c16c94ea99%7C0%7C0%7C636397211330551372&sdata=afQLw7%2FVip%2Bts1P60ALOHrTNap93519tWLjYzkS2o5Q%3D&reserved=0"><u><font size="2" color="#0000FF" face="Helvetica">https://lists.swift.org/mailman/listinfo/swift-corelibs-dev</font></u></a></ul></ul></ul></ul><font size="2" face="Courier New">_______________________________________________<br>swift-corelibs-dev mailing list<br>swift-corelibs-dev@swift.org</font><u><font size="2" color="#0000FF" face="Courier New"><br></font></u><a href="https://urldefense.proofpoint.com/v2/url?u=https-3A__na01.safelinks.protection.outlook.com_-3Furl-3Dhttps-253A-252F-252Furldefense.proofpoint.com-252Fv2-252Furl-253Fu-253Dhttps-2D3A-5F-5Flists.swift.org-5Fmailman-5Flistinfo-5Fswift-2D2Dcorelibs-2D2Ddev-2526d-253DDwIGaQ-2526c-253Djf-5FiaSHvJObTbx-2DsiA1ZOg-2526r-253DgkRZBtsmKeGPCOlAIRJoOA-2526m-253DViDSVPImta3StTVAcktby2PMF-5F-2Ddu5itzz47jo-2DtNHg-2526s-253DzRuNQ3NLxpfhFBewRTkoMWZnpvHlm6Ja-2Dot9-5FpwAgqI-2526e-253D-26data-3D02-257C01-257Cbrsneed-2540ebay.com-257C6290a819253b47b0eb2408d4efe454ae-257C46326bff992841a0baca17c16c94ea99-257C0-257C0-257C636397211330551372-26sdata-3DkUgv-252B3QRVpUH5JGBclTqYHheS-252FfaDPIWTrTk-252F-252BX8J-252Bs-253D-26reserved-3D0&d=DwMGaQ&c=jf_iaSHvJObTbx-siA1ZOg&r=gkRZBtsmKeGPCOlAIRJoOA&m=c3lYikOfd2-4q_nd_qMnJ4gXKIuKuxxoJRxIrIZc3Hw&s=lhWK6MIAPUmU4rsIhtD7P7EgacPwfGk17SvpQdMJogc&e="><u><font size="2" color="#0000FF" face="Courier New">https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.swift.org_mailman_listinfo_swift-2Dcorelibs-2Ddev&amp;d=DwIGaQ&amp;c=jf_iaSHvJObTbx-siA1ZOg&amp;r=gkRZBtsmKeGPCOlAIRJoOA&amp;m=ViDSVPImta3StTVAcktby2PMF_-du5itzz47jo-tNHg&amp;s=zRuNQ3NLxpfhFBewRTkoMWZnpvHlm6Ja-ot9_pwAgqI&amp;e=</font></u></a><font size="2" face="Courier New"> </font><font face="Times New Roman"><br><br><br><br></font><br><br><BR>
</body></html>