<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hi Jon,<br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Jun 22, 2017, at 6:00 PM, Jon Shier &lt;<a href="mailto:jon@jonshier.com" class="">jon@jonshier.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Tony:<div class=""><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>My main concern here is that, as Swift’s official JSON parsing method, Codable should be able to handle any JSON representation and use and it doesn’t. In fact, it can’t. If that’s considered okay by the designers of the library and Apple itself, then fine. I think it’s silly (just like I think it’s silly that, after years of waiting, NSISO8601DateFormatter doesn’t actually support the full ISO 8601 standard) and does a disservice to developers, but fine. For example, many JSON APIs (from the very worst to some of the best) use a common reply structure:</div><div class=""><br class=""></div><div class="">{</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>“value” : { } or null</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>“error” : { } or null</div><div class="">}</div><div class=""><br class=""></div><div class="">Having implemented a few of these using Argo, I usually follow a common pattern:</div><div class=""><br class=""></div><div class="">struct APIResponse: Argo.Decodable {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let value: JSON?</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>let error: APIError?</div><div class="">}</div><div class=""><br class=""></div><div class="">I then decode the response, check to see which of the parts is non-null, and continue decoding based on that result. I decode the value based on the generic type passed in, usually in an Alamofire response serializer. Codable can sort of represent this, with this:</div><div class=""><br class=""></div><div class="">struct&nbsp;APIResponse&lt;T:&nbsp;Decodable&gt;:&nbsp;Decodable&nbsp;{<br class="">&nbsp; &nbsp;&nbsp;let&nbsp;value:&nbsp;T?<br class="">&nbsp; &nbsp;&nbsp;let&nbsp;error:&nbsp;String? // String as I haven’t defined an error type.<br class="">}</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>This works, AFAICT, but loses the rather important ability to inspect the decoding result before attempting to decode the generic value. Codable would be perfectly happy to return me an APIResponse with two nil values, which is an invalid state for this API and should be an error. (As an aside, defaulting all errors for optional values to nil is poor practice and we lose some error fidelity there.) This is really just a symptom of Foundation not having a real JSON limitation. But it’s doubly concerning that the JSON representation it does have, Any, can’t be parsed by it’s own JSON decoder.&nbsp;</div></div></div></div></blockquote><div><br class=""></div>Have you considered using an enum?</div><div><br class=""></div><div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">let jsonA = <span style="color: #d12f1b" class="">"""</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">{</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">"key1" : 1</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">}</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #d12f1b" class="">"""</span>.<span style="color: #3e1e81" class="">data</span>(using: .<span style="color: #703daa" class="">utf8</span>)!</div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">let jsonB = <span style="color: #d12f1b" class="">"""</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">{</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">"key2" : "foo"</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">}</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #d12f1b" class="">"""</span>.<span style="color: #3e1e81" class="">data</span>(using: .<span style="color: #703daa" class="">utf8</span>)!</div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">enum</span> EitherOr : <span style="color: #703daa" class="">Decodable</span> {</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; <span style="color: #ba2da2" class="">case</span> A(<span style="color: #703daa" class="">Int</span>)</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; <span style="color: #ba2da2" class="">case</span> B(<span style="color: #703daa" class="">String</span>)</div><p style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255); min-height: 14px;" class="">&nbsp;&nbsp; &nbsp;<br class="webkit-block-placeholder"></p><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; <span style="color: #ba2da2" class="">private</span> <span style="color: #ba2da2" class="">enum</span> CodingKeys : <span style="color: #703daa" class="">CodingKey</span> { <span style="color: #ba2da2" class="">case</span> key1; <span style="color: #ba2da2" class="">case</span> key2 }</div><p style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255); min-height: 14px;" class="">&nbsp;&nbsp; &nbsp;<br class="webkit-block-placeholder"></p><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; <span style="color: #ba2da2" class="">init</span>(from decoder: <span style="color: #703daa" class="">Decoder</span>) <span style="color: #ba2da2" class="">throws</span> {</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ba2da2" class="">let</span> c = <span style="color: #ba2da2" class="">try</span> decoder.<span style="color: #3e1e81" class="">container</span>(keyedBy: <span style="color: #4f8187" class="">CodingKeys</span>.<span style="color: #ba2da2" class="">self</span>)</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ba2da2" class="">if</span> c.<span style="color: #3e1e81" class="">contains</span>(.<span style="color: #31595d" class="">key1</span>) {</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ba2da2" class="">self</span> = .<span style="color: #31595d" class="">A</span>(<span style="color: #ba2da2" class="">try</span> c.<span style="color: #3e1e81" class="">decode</span>(<span style="color: #703daa" class="">Int</span>.<span style="color: #ba2da2" class="">self</span>, forKey: .<span style="color: #31595d" class="">key1</span>))</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; &nbsp; &nbsp; } <span style="color: #ba2da2" class="">else</span> <span style="color: #ba2da2" class="">if</span> c.<span style="color: #3e1e81" class="">contains</span>(.<span style="color: #31595d" class="">key2</span>) {</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ba2da2" class="">self</span> = .<span style="color: #31595d" class="">B</span>(<span style="color: #ba2da2" class="">try</span> c.<span style="color: #3e1e81" class="">decode</span>(<span style="color: #703daa" class="">String</span>.<span style="color: #ba2da2" class="">self</span>, forKey: .<span style="color: #31595d" class="">key2</span>))</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; &nbsp; &nbsp; } <span style="color: #ba2da2" class="">else</span> {</div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255);" class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </font><span style="font-family: Menlo; color: rgb(186, 45, 162);" class="">throw</span> <span style="font-family: Menlo; color: rgb(112, 61, 170);" class="">DecodingError</span><font face="Menlo" class="">.</font><span style="font-family: Menlo; color: rgb(62, 30, 129);" class="">dataCorrupted</span><font face="Menlo" class="">(</font><span style="font-family: Menlo; color: rgb(112, 61, 170);" class="">DecodingError</span><font face="Menlo" class="">.</font><span style="font-family: Menlo; color: rgb(112, 61, 170);" class="">Context</span><font face="Menlo" class="">(codingPath: [], debugDescription: </font><span style="font-family: Menlo; color: rgb(209, 47, 27);" class="">"</span><font color="#d12f1b" face="Menlo" class="">”</font><font face="Menlo" class="">))</font></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; }</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">}</div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">let</span> decoder = <span style="color: #703daa" class="">JSONDecoder</span>()</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">let</span> result1 = <span style="color: #ba2da2" class="">try</span>! <span style="color: #4f8187" class="">decoder</span>.<span style="color: #3e1e81" class="">decode</span>(<span style="color: #4f8187" class="">EitherOr</span>.<span style="color: #ba2da2" class="">self</span>, from: <span style="color: #4f8187" class="">jsonA</span>)</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);" class=""><span style="color: #3e1e81" class="">print</span><span style="color: #000000" class="">(</span>result1<span style="color: #000000" class="">)</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">let</span> result2 = <span style="color: #ba2da2" class="">try</span>! <span style="color: #4f8187" class="">decoder</span>.<span style="color: #3e1e81" class="">decode</span>(<span style="color: #4f8187" class="">EitherOr</span>.<span style="color: #ba2da2" class="">self</span>, from: <span style="color: #4f8187" class="">jsonB</span>)</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135); background-color: rgb(255, 255, 255);" class=""><span style="color: #3e1e81" class="">print</span><span style="color: #000000" class="">(</span>result2<span style="color: #000000" class="">)</span></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;" class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">A(1)</b></span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">B("foo")</b></span></div><div class=""><br class=""></div></div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class=""><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>Dealing with data also limits Codable’s use for JSON to only things that have data representation. For example, push notifications can contain custom JSON payloads. On Apple platforms the push handler automatically decodes this JSON before passing the result to the delegates in the app. In the past I’ve been able to use the same JSON representations to parse the Any returned by the push delegates as I do in my networking API, which gives me exactly the same parsing for both methods. Codable can’t be used here.&nbsp;</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>In addition, Codable’s cumbersome API for custom APIs is rather painful to deal with, and the official recommended solution to use *Raw types that come from your API and are used to initialize your “real” types is untenable (on one project, every type I got in a response wouldn’t have required this, forcing me to maintain 60 types, manually). Add to that the manual nature of any sort of transform or validation, and Codable for real JSON decoding becomes rather painful.</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>For me, this means that I’ll likely stick to libraries like Argo for actual JSON decoding (greater fidelity and flexibility in far less code) and use Codable for disk and other transfer representations (I look forward to writing my watch communication using it) only, in all but the most ideal circumstances (if I design the JSON API I can optimize it around Codable).</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Jon Shier</div></div></div></div></blockquote><div><br class=""></div>Sure, there is only so much we can do completely automatically. One of our goals was to make the simplest stuff possible with as little boilerplate as possible, but provide the ability to customize when you want to do something more advanced (as above).</div><div><br class=""></div><div>- Tony</div><div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class=""><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span></div><div class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Jun 22, 2017, at 7:10 PM, Tony Parker &lt;<a href="mailto:anthony.parker@apple.com" class="">anthony.parker@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hi Jon,<div class=""><br class=""></div><div class="">Usually this boils down to a question of: what are you going to <i class="">do</i>&nbsp;with the Any?<div class=""><br class=""></div><div class="">If you intended to cast it to a dictionary and get at its values using string keys, then writing a struct with the properties you care about is the way we recommend doing this. You don’t have to include every possible key.</div><div class=""><br class=""></div><div class="">There are some more dynamic behaviors possible with the Any, but the point of this API was to try to move a lot of the parsing into a place where the compiler could help you not only to generate the boilerplate but catch errors at compile time.</div><div class=""><br class=""></div><div class="">The omission of an API to just get the rest of the data as some kind of Any is both for reasons of abstraction (not every data format is JSON, and the Any truly could be anything in other formats), and a statement of intent of how we believe this API is best used.</div><div class=""><br class=""></div><div class="">- Tony<br class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Jun 18, 2017, at 7:23 PM, Jon Shier via swift-users &lt;<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Given that, per his description, “metadata” can be anything, creating a struct doesn’t really help.<div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Jon Shier</div><div class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On Jun 18, 2017, at 9:00 PM, somu subscribe &lt;<a href="mailto:somu.subscribe@gmail.com" class="">somu.subscribe@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Create a <font face="Menlo" color="#0433ff" class="">struct</font> for Metadata and conform to <font color="#0433ff" face="Menlo" class="">Coding</font></div><div class=""><br class=""></div><div class=""><b class="">Code:</b></div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">let</span> string = <span style="color: #d12f1b" class="">"""</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">{</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">&nbsp; "id": "4yq6txdpfadhbaqnwp3",</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">&nbsp; "email": "<a href="mailto:john.doe@example.com" class="">john.doe@example.com</a>",</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">&nbsp; "name":"John Doe",</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">&nbsp; "metadata": {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; "link_id": "linked-id",</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; "buy_count": 4</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">&nbsp; }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">}</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">"""</div><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">let</span><span style="" class=""> data = </span><span style="color: #4f8187" class="">string</span><span style="" class="">.</span><span style="color: #3e1e81" class="">data</span><span style="" class="">(using: .</span><span style="color: #703daa" class="">utf8</span><span style="" class="">)! </span>//Force unwrapping just for ease of explanation, use guard instead</div><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">struct</span> User: <span style="color: #703daa" class="">Codable</span> {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255); min-height: 13px;" class="">&nbsp;&nbsp; &nbsp;<br class="webkit-block-placeholder"></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);" class=""><span style="" class="">&nbsp; &nbsp; </span>//Struct to handle the nested JSON</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; <span style="color: #ba2da2" class="">struct</span> Metadata : <span style="color: #703daa" class="">Codable</span> {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ba2da2" class="">var</span> linkID &nbsp; : <span style="color: #703daa" class="">String</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ba2da2" class="">var</span> buyCount : <span style="color: #703daa" class="">Int</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255); min-height: 13px;" class="">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;<br class="webkit-block-placeholder"></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);" class=""><span style="" class="">&nbsp; &nbsp; &nbsp; &nbsp; </span>//Customisation, if you want if you want your properties to be different from the JSON key</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ba2da2" class="">private</span> <span style="color: #ba2da2" class="">enum</span> CodingKeys : <span style="color: #703daa" class="">String</span>, <span style="color: #703daa" class="">CodingKey</span> {</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ba2da2" class="">case</span> linkID &nbsp; &nbsp; = <span style="color: #d12f1b" class="">"link_id"</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ba2da2" class="">case</span> buyCount &nbsp; = <span style="color: #d12f1b" class="">"buy_count"</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; }</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255); min-height: 13px;" class="">&nbsp;&nbsp; &nbsp;<br class="webkit-block-placeholder"></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; <span style="color: #ba2da2" class="">var</span> id: <span style="color: #703daa" class="">String</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; <span style="color: #ba2da2" class="">var</span> email&nbsp; &nbsp; : <span style="color: #703daa" class="">String</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; <span style="color: #ba2da2" class="">var</span> name &nbsp; &nbsp; : <span style="color: #703daa" class="">String</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; <span style="color: #ba2da2" class="">var</span> metadata : <span style="color: #4f8187" class="">Metadata</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">}</div><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="color: #ba2da2" class="">let</span> decoder = <span style="color: #703daa" class="">JSONDecoder</span>()</div><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);" class="">do<span style="" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; <span style="color: #ba2da2" class="">let</span> user = <span style="color: #ba2da2" class="">try</span> <span style="color: #4f8187" class="">decoder</span>.<span style="color: #3e1e81" class="">decode</span>(<span style="color: #4f8187" class="">User</span>.<span style="color: #ba2da2" class="">self</span>, from: <span style="color: #4f8187" class="">data</span>)</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; <span style="color: #3e1e81" class="">print</span>(user)</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">}</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);" class="">catch<span style="" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; <span style="color: #3e1e81" class="">print</span>(<span style="color: #d12f1b" class="">"error:</span>\<span style="color: #d12f1b" class="">(</span>error<span style="color: #d12f1b" class="">)"</span>)</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class="">}</div></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><span style="font-family: Helvetica; font-size: 12px;" class=""><b class="">Reference:</b></span></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);" class=""><br class=""></div></div><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255);" class=""><a href="https://developer.apple.com/videos/play/wwdc2017/212/" class="">https://developer.apple.com/videos/play/wwdc2017/212/</a></div><div class=""><b class=""><br class=""></b></div><div class=""><br class=""></div><div class="">Regards,</div><div class="">Muthu</div><div class=""><br class=""></div><div class=""><br class=""></div><br class=""><div class=""><blockquote type="cite" class=""><div class="">On 19 Jun 2017, at 3:29 AM, Jon Shier via swift-users &lt;<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>The more I use Codable, the less suited to networking it becomes. In reading a variety of blog posts about implementing custom Decodable support from JSON, I kept running across the same pattern. Basically, users had started implementing their own decoding protocols which wrap Decodable types, and have a type that represents the JSON representation and then their real type, with an initializer connecting the two. But apparently this is Apple’s official solution, which is rather terrible since it would be completely unnecessary if the Decodable APIs were more flexible or we could access keys by key path rather than nesting full containers. I can’t image how much code I would have to add to decode the nasty JSON APIs I’ve used Argo to parse before. Every type would need an underlying raw representation that, at the very least, would need custom keys, lest I pollute even those models with the terrible keys the JSON actually has. Not to mention the various transforms I needed. Once I hit any reasonably complex API, Argo is far far simpler to implement in fewer lines of code.<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>In trying to make Argo’s JSON enum Decodable itself, I can’t seem to find a way to access the Any representation of the raw JSON. In fact, it appears there’s no way to represent an Any value in Codable at all, which makes Codable rather useless for the scenarios like the one that prompted this thread. Without such an ability it’s impossible to actually use Codable with all of the JSON out there, where other solutions work just fine. Argo’s JSON type is decodable by Argo, so you can use it to represent a blob of JSON just fine. Other existing JSON frameworks have similar solutions. <br class=""><br class=""><br class=""><br class="">Jon<br class=""><br class=""><blockquote type="cite" class="">On Jun 18, 2017, at 3:21 AM, Rien via swift-users &lt;<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>&gt; wrote:<br class=""><br class="">Dang, hit send too soon. Sorry.<br class=""><br class="">This does not address your question, so please ignore… (foot in mouth)!<br class=""><br class="">Regards,<br class="">Rien<br class=""><br class="">Site: <a href="http://balancingrock.nl/" class="">http://balancingrock.nl</a><br class="">Blog: <a href="http://swiftrien.blogspot.com/" class="">http://swiftrien.blogspot.com</a><br class="">Github: <a href="http://github.com/Balancingrock" class="">http://github.com/Balancingrock</a><br class="">Project: <a href="http://swiftfire.nl/" class="">http://swiftfire.nl</a> - An HTTP(S) web server framework in Swift<br class=""><br class=""><br class=""><br class=""><br class=""><br class=""><br class=""><br class=""><blockquote type="cite" class="">On 18 Jun 2017, at 09:19, Rien &lt;<a href="mailto:Rien@Balancingrock.nl" class="">Rien@Balancingrock.nl</a>&gt; wrote:<br class=""><br class="">Are you looking for a general purpose JSON interpreter / API ?<br class=""><br class="">There are many of them around, and in fact I do have my own: <a href="https://github.com/Balancingrock/VJson" class="">https://github.com/Balancingrock/VJson</a><br class=""><br class="">With VJson I would write:<br class=""><br class="">let json = VJson.parse(… your json object…)<br class=""><br class="">and then access the metadata as:<br class=""><br class="">let buyCount = (json | ”metadata” | ”buy_count”)?.intValue<br class=""><br class="">or:<br class=""><br class="">var buyCount: Int &amp;= json | “metadata” | “buy_count”<br class=""><br class="">To loop over the content of metadata:<br class=""><br class="">for item in (json | “metadata”) ?? [ ] {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>print (item.nameValue)<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>switch item.type {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>case .object: …<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>case .number: …<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>case .string: …<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>etc...<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}<br class="">}<br class=""><br class="">Obviously I am plugging my own code here, but there are many others around, I understand that SwiftyJSON is quite popular but I have not used that myself.<br class=""><br class="">Regards,<br class="">Rien<br class=""><br class="">Site: <a href="http://balancingrock.nl/" class="">http://balancingrock.nl</a><br class="">Blog: <a href="http://swiftrien.blogspot.com/" class="">http://swiftrien.blogspot.com</a><br class="">Github: <a href="http://github.com/Balancingrock" class="">http://github.com/Balancingrock</a><br class="">Project: <a href="http://swiftfire.nl/" class="">http://swiftfire.nl</a> - An HTTP(S) web server framework in Swift<br class=""><br class=""><br class=""><br class=""><br class=""><br class=""><br class=""><br class=""><blockquote type="cite" class="">On 18 Jun 2017, at 04:07, Chris Anderson via swift-users &lt;<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>&gt; wrote:<br class=""><br class="">Say I have a JSON object such as:<br class=""><br class="">{<br class=""> &nbsp;"id": "4yq6txdpfadhbaqnwp3",<br class=""> &nbsp;"email": "<a href="mailto:john.doe@example.com" class="">john.doe@example.com</a>",<br class=""> &nbsp;"name":"John Doe",<br class=""> &nbsp;"metadata": {<br class=""> &nbsp;&nbsp;&nbsp;"link_id": "linked-id",<br class=""> &nbsp;&nbsp;&nbsp;"buy_count": 4<br class=""> &nbsp;}<br class="">}<br class=""><br class="">And with a struct of:<br class=""><br class="">struct User: Codable {<br class="">var id: String<br class="">var email: String<br class="">var name: String<br class="">}<br class=""><br class="">How can I decode the `metadata` field into a Dictionary?<br class=""><br class="">I’ve tried doing things such as, in my struct,<br class=""><br class="">var metadata: Dictionary<br class=""><br class="">or<br class=""><br class="">var metadata: [String: Any]<br class=""><br class="">But I get the error <br class=""><br class="">MyPlayground.playground:3:7: note: cannot automatically synthesize 'Encodable' because '&lt;&lt;error type&gt;&gt;' does not conform to 'Encodable'<br class="">var metadata: Dictionary <br class=""><br class="">A meta or metadata field on many APIs (such as <a href="http://www.stripe.com/" class="">www.stripe.com</a>) can contain whatever you want, and I still want to be able to process it on the Swift end. How can I store that meta data field into a Dictionary that I can parse apart manually after?<br class=""><br class="">Thanks!<br class=""><br class="">Chris Anderson<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><br class=""><br class=""><br class=""><br class="">_______________________________________________<br class="">swift-users mailing list<br class=""><a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-users" class="">https://lists.swift.org/mailman/listinfo/swift-users</a><br class=""></blockquote><br class=""></blockquote><br class="">_______________________________________________<br class="">swift-users mailing list<br class=""><a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-users" class="">https://lists.swift.org/mailman/listinfo/swift-users</a><br class=""></blockquote><br class="">_______________________________________________<br class="">swift-users mailing list<br class=""><a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-users" class="">https://lists.swift.org/mailman/listinfo/swift-users</a><br class=""></div></div></blockquote></div><br class=""></div></div></blockquote></div><br class=""></div></div>_______________________________________________<br class="">swift-users mailing list<br class=""><a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-users" class="">https://lists.swift.org/mailman/listinfo/swift-users</a><br class=""></div></blockquote></div><br class=""></div></div></div></div></blockquote></div><br class=""></div></div></div></div></blockquote></div><br class=""></body></html>