<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jun 17, 2017, at 10:07 PM, Chris Anderson 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; -webkit-line-break: after-white-space;" class="">Say I have a JSON object such as:<div class=""><br class=""></div><div class=""><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">&nbsp;&nbsp;{</div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; "id": "4yq6txdpfadhbaqnwp3",</div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; "email": "<a href="mailto:john.doe@example.com" class="">john.doe@example.com</a>",</div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; "name":"John Doe",</div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; "metadata": {</div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; &nbsp; "link_id": "linked-id",</div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; &nbsp; "buy_count": 4</div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">&nbsp; &nbsp; }</div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class="">&nbsp; }</div></div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class=""><br class=""></div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class=""><span style="font-family: Helvetica;" class="">And with a struct of:</span></div><div style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);" class=""><span style="font-family: Helvetica;" class=""><br class=""></span></div><div style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255);" class=""><div style="font-family: Menlo; margin: 0px; line-height: normal;" class=""><span style="color: #ba2da2" class="">struct</span> User: <span style="color: #703daa" class="">Codable</span> {</div><div style="font-family: Menlo; margin: 0px; line-height: normal;" class="">&nbsp; <span style="color: #ba2da2" class="">var</span> id: <span style="color: #703daa" class="">String</span></div><div style="font-family: Menlo; margin: 0px; line-height: normal;" class="">&nbsp; <span style="color: #ba2da2" class="">var</span> email: <span style="color: #703daa" class="">String</span></div><div style="font-family: Menlo; margin: 0px; line-height: normal;" class="">&nbsp; <span style="color: #ba2da2" class="">var</span> name: <span style="color: #703daa" class="">String</span></div><div style="font-family: Menlo; color: rgb(0, 132, 0); margin: 0px; line-height: normal;" class=""><span style="" class="">}</span></div><div style="font-family: Menlo; color: rgb(0, 132, 0); margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><div style="margin: 0px; line-height: normal;" class="">How can I decode the `metadata` field into a Dictionary?</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">I’ve tried doing things such as, in my struct,</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-family: Menlo; color: rgb(186, 45, 162);" class="">var</span><span style="font-family: Menlo;" class="">&nbsp;</span><span style="font-family: Menlo;" class="">metadata:</span><span style="font-family: Menlo;" class="">&nbsp;</span><span style="font-family: Menlo; color: rgb(112, 61, 170);" class="">Dictionary</span></div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">or</div><div style="margin: 0px; line-height: normal;" class=""><span style="font-family: Menlo; color: rgb(112, 61, 170);" class=""><br class=""></span></div><div style="margin: 0px; line-height: normal;" class=""><div style="margin: 0px; line-height: normal;" class=""><span style="font-family: Menlo; color: rgb(186, 45, 162);" class="">var</span><span style="font-family: Menlo;" class="">&nbsp;</span><span style="font-family: Menlo;" class="">metadata:</span><span style="font-family: Menlo;" class="">&nbsp;</span><span style="font-family: Menlo; color: rgb(112, 61, 170);" class="">[String: Any]</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-family: Menlo; color: rgb(112, 61, 170);" class=""><br class=""></span></div><div style="margin: 0px; line-height: normal;" class="">But I get the error&nbsp;</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">MyPlayground.playground:3:7: note: cannot automatically synthesize 'Encodable' because '&lt;&lt;error type&gt;&gt;' does not conform to&nbsp;'Encodable'</div><div style="margin: 0px; line-height: normal;" class="">&nbsp;&nbsp;var metadata: Dictionary<span style="font-family: Menlo; color: rgb(112, 61, 170);" class="">&nbsp;</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-family: Menlo; color: rgb(112, 61, 170);" class=""><br class=""></span></div><div style="margin: 0px; line-height: normal;" 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?</div></div></div></div></div></div></blockquote><br class=""></div><div>It’s possible, but you have to do most of the work yourself because you the compiler can’t create implementations for you. See below for a possible implementation. Note that I just ignore types I don’t handle. I also took a stab at doing something general in this gist (<a href="https://gist.github.com/kenada/069e121371eb8db41231edfcd4bd14a8" class="">https://gist.github.com/kenada/069e121371eb8db41231edfcd4bd14a8</a>), but it doesn’t implement very robust error handling or support encoding. It also doesn’t flatten down to Any/[Any]/[String: Any] (leaving it up to the user to destructure the enum).</div><br class=""><div class=""><div class=""><font face="Menlo" class="">import Foundation</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">struct User: Codable {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; var id: String</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; var email: String</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; var name: String</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; var metadata: [String: Any]</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; init(from decoder: Decoder) throws {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; let container = try decoder.container(keyedBy: StaticCodingKeys.self)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; self.id = try container.decode(String.self, forKey: .id)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; self.email = try container.decode(String.self, forKey: .email)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; self.name = try container.decode(String.self, forKey: .name)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; self.metadata = try User.decodeMetadata(from: container.superDecoder(forKey: .metadata))</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; }</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; func encode(to encoder: Encoder) throws {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; var container = encoder.container(keyedBy: StaticCodingKeys.self)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; try container.encode(self.id, forKey: .id)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; try container.encode(self.email, forKey: .email)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; try container.encode(self.name, forKey: .name)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; try encodeMetadata(to: container.superEncoder(forKey: .metadata))</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; }</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp;static func decodeMetadata(from decoder: Decoder) throws -&gt; [String: Any] {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; let container = try decoder.container(keyedBy: DynamicCodingKeys.self)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; var result: [String: Any] = [:]</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; for key in container.allKeys {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if let double = try? container.decode(Double.self, forKey: key) {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result[key.stringValue] = double</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else if let string = try? container.decode(String.self, forKey: key) {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result[key.stringValue] = string</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; return result</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; }</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; func encodeMetadata(to encoder: Encoder) throws {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; var container = encoder.container(keyedBy: DynamicCodingKeys.self)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; for (key, value) in metadata {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; switch value {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case let double as Double:</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try container.encode(double, forKey: DynamicCodingKeys(stringValue: key)!)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case let string as String:</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try container.encode(string, forKey: DynamicCodingKeys(stringValue: key)!)</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fatalError("unexpected type")</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; }</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; private enum StaticCodingKeys: String, CodingKey {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; case id, email, name, metadata</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; }</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; private struct DynamicCodingKeys: CodingKey {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; var stringValue: String</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; init?(stringValue: String) {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.stringValue = stringValue</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; var intValue: Int?</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; init?(intValue: Int) {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.init(stringValue: "")</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.intValue = intValue</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; }</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; }</font></div><div class=""><font face="Menlo" class="">}</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">let userJson = """</font></div><div class=""><font face="Menlo" class="">&nbsp; {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; "id": "4yq6txdpfadhbaqnwp3",</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; "email": "<a href="mailto:john.doe@example.com" class="">john.doe@example.com</a>",</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; "name":"John Doe",</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; "metadata": {</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; "link_id": "linked-id",</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; "buy_count": 4</font></div><div class=""><font face="Menlo" class="">&nbsp; &nbsp; }</font></div><div class=""><font face="Menlo" class="">&nbsp; }</font></div><div class=""><font face="Menlo" class="">""".data(using: .utf8)!</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">let decoder = JSONDecoder()</font></div><div class=""><font face="Menlo" class="">let user = try! decoder.decode(User.self, from: userJson)</font></div><div class=""><font face="Menlo" class="">print(user)</font></div><div class=""><font face="Menlo" class="">// Prints:&nbsp;User(id: "4yq6txdpfadhbaqnwp3", email: "<a href="mailto:john.doe@example.com" class="">john.doe@example.com</a>", name: "John Doe", metadata: ["buy_count": 4.0, "link_id": "linked-id"])</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class="">let encoder = JSONEncoder()</font></div><div class=""><font face="Menlo" class="">let data = try! encoder.encode(user)</font></div><div class=""><font face="Menlo" class="">print(String(data: data, encoding: .utf8)!)</font></div></div><div class=""><font face="Menlo" class="">// Prints:&nbsp;{"email":"<a href="mailto:john.doe@example.com" class="">john.doe@example.com</a>","id":"4yq6txdpfadhbaqnwp3","metadata":{"link_id":"linked-id","buy_count":4},"name":"John Doe"}</font></div><div class=""><br class=""></div><div class="">--&nbsp;</div><div class="">Randy Eckenrode</div></body></html>