<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=""><span class="Apple-tab-span" style="white-space:pre">        </span>Your gist is extremely interesting to me. I had tried something similar with Argo’s existing JSON enum, but was somewhat stymied by trying to decode it from an unkeyed container. I suppose I still don’t have a good grasp on all of the existing container types.<div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Jon</div><div class=""><br class=""></div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jun 23, 2017, at 11:46 AM, Randy Eckenrode via swift-users <<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class=""><br class="Apple-interchange-newline">On Jun 17, 2017, at 10:07 PM, Chris Anderson via swift-users <<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">Say I have a JSON object such as:<div class=""><br class=""></div><div class=""><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);"> {</div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);"> "id": "4yq6txdpfadhbaqnwp3",</div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);"> "email": "<a href="mailto:john.doe@example.com" class="">john.doe@example.com</a>",</div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);"> "name":"John Doe",</div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);"> "metadata": {</div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);"> "link_id": "linked-id",</div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);"> "buy_count": 4</div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);"> }</div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);"> }</div></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);"><br class=""></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);"><span class="" style="font-family: Helvetica;">And with a struct of:</span></div><div class="" style="margin: 0px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27); background-color: rgb(255, 255, 255);"><span class="" style="font-family: Helvetica;"><br class=""></span></div><div class="" style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255);"><div class="" style="font-family: Menlo; margin: 0px; line-height: normal;"><span class="" style="color: rgb(186, 45, 162);">struct</span><span class="Apple-converted-space"> </span>User:<span class="Apple-converted-space"> </span><span class="" style="color: rgb(112, 61, 170);">Codable</span><span class="Apple-converted-space"> </span>{</div><div class="" style="font-family: Menlo; margin: 0px; line-height: normal;"> <span class="Apple-converted-space"> </span><span class="" style="color: rgb(186, 45, 162);">var</span><span class="Apple-converted-space"> </span>id:<span class="Apple-converted-space"> </span><span class="" style="color: rgb(112, 61, 170);">String</span></div><div class="" style="font-family: Menlo; margin: 0px; line-height: normal;"> <span class="Apple-converted-space"> </span><span class="" style="color: rgb(186, 45, 162);">var</span><span class="Apple-converted-space"> </span>email:<span class="Apple-converted-space"> </span><span class="" style="color: rgb(112, 61, 170);">String</span></div><div class="" style="font-family: Menlo; margin: 0px; line-height: normal;"> <span class="Apple-converted-space"> </span><span class="" style="color: rgb(186, 45, 162);">var</span><span class="Apple-converted-space"> </span>name:<span class="Apple-converted-space"> </span><span class="" style="color: rgb(112, 61, 170);">String</span></div><div class="" style="font-family: Menlo; color: rgb(0, 132, 0); margin: 0px; line-height: normal;"><span class="">}</span></div><div class="" style="font-family: Menlo; color: rgb(0, 132, 0); margin: 0px; line-height: normal;"><br class=""></div><div class="" style="margin: 0px; line-height: normal;"><div class="" style="margin: 0px; line-height: normal;">How can I decode the `metadata` field into a Dictionary?</div><div class="" style="margin: 0px; line-height: normal;"><br class=""></div><div class="" style="margin: 0px; line-height: normal;">I’ve tried doing things such as, in my struct,</div><div class="" style="margin: 0px; line-height: normal;"><br class=""></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-family: Menlo; color: rgb(186, 45, 162);">var</span><span class="" style="font-family: Menlo;"> </span><span class="" style="font-family: Menlo;">metadata:</span><span class="" style="font-family: Menlo;"> </span><span class="" style="font-family: Menlo; color: rgb(112, 61, 170);">Dictionary</span></div><div class="" style="margin: 0px; line-height: normal;"><br class=""></div><div class="" style="margin: 0px; line-height: normal;">or</div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-family: Menlo; color: rgb(112, 61, 170);"><br class=""></span></div><div class="" style="margin: 0px; line-height: normal;"><div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-family: Menlo; color: rgb(186, 45, 162);">var</span><span class="" style="font-family: Menlo;"> </span><span class="" style="font-family: Menlo;">metadata:</span><span class="" style="font-family: Menlo;"> </span><span class="" style="font-family: Menlo; color: rgb(112, 61, 170);">[String: Any]</span></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-family: Menlo; color: rgb(112, 61, 170);"><br class=""></span></div><div class="" style="margin: 0px; line-height: normal;">But I get the error </div><div class="" style="margin: 0px; line-height: normal;"><br class=""></div><div class="" style="margin: 0px; line-height: normal;">MyPlayground.playground:3:7: note: cannot automatically synthesize 'Encodable' because '<<error type>>' does not conform to 'Encodable'</div><div class="" style="margin: 0px; line-height: normal;"> var metadata: Dictionary<span class="" style="font-family: Menlo; color: rgb(112, 61, 170);"> </span></div><div class="" style="margin: 0px; line-height: normal;"><span class="" style="font-family: Menlo; color: rgb(112, 61, 170);"><br class=""></span></div><div class="" style="margin: 0px; line-height: normal;">A meta or metadata field on many APIs (such as<span class="Apple-converted-space"> </span><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 style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">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="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><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=""> var id: String</font></div><div class=""><font face="Menlo" class=""> var email: String</font></div><div class=""><font face="Menlo" class=""> var name: String</font></div><div class=""><font face="Menlo" class=""> var metadata: [String: Any]</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class=""> init(from decoder: Decoder) throws {</font></div><div class=""><font face="Menlo" class=""> let container = try decoder.container(keyedBy: StaticCodingKeys.self)</font></div><div class=""><font face="Menlo" class=""> self.id = try container.decode(String.self, forKey: .id)</font></div><div class=""><font face="Menlo" class=""> self.email = try container.decode(String.self, forKey: .email)</font></div><div class=""><font face="Menlo" class=""> self.name = try container.decode(String.self, forKey: .name)</font></div><div class=""><font face="Menlo" class=""> self.metadata = try User.decodeMetadata(from: container.superDecoder(forKey: .metadata))</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=""> func encode(to encoder: Encoder) throws {</font></div><div class=""><font face="Menlo" class=""> var container = encoder.container(keyedBy: StaticCodingKeys.self)</font></div><div class=""><font face="Menlo" class=""> try container.encode(self.id, forKey: .id)</font></div><div class=""><font face="Menlo" class=""> try container.encode(self.email, forKey: .email)</font></div><div class=""><font face="Menlo" class=""> try container.encode(self.name, forKey: .name)</font></div><div class=""><font face="Menlo" class=""> try encodeMetadata(to: container.superEncoder(forKey: .metadata))</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=""> static func decodeMetadata(from decoder: Decoder) throws -> [String: Any] {</font></div><div class=""><font face="Menlo" class=""> let container = try decoder.container(keyedBy: DynamicCodingKeys.self)</font></div><div class=""><font face="Menlo" class=""> var result: [String: Any] = [:]</font></div><div class=""><font face="Menlo" class=""> for key in container.allKeys {</font></div><div class=""><font face="Menlo" class=""> if let double = try? container.decode(Double.self, forKey: key) {</font></div><div class=""><font face="Menlo" class=""> result[key.stringValue] = double</font></div><div class=""><font face="Menlo" class=""> } else if let string = try? container.decode(String.self, forKey: key) {</font></div><div class=""><font face="Menlo" class=""> result[key.stringValue] = string</font></div><div class=""><font face="Menlo" class=""> }</font></div><div class=""><font face="Menlo" class=""> }</font></div><div class=""><font face="Menlo" class=""> return result</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=""> func encodeMetadata(to encoder: Encoder) throws {</font></div><div class=""><font face="Menlo" class=""> var container = encoder.container(keyedBy: DynamicCodingKeys.self)</font></div><div class=""><font face="Menlo" class=""> for (key, value) in metadata {</font></div><div class=""><font face="Menlo" class=""> switch value {</font></div><div class=""><font face="Menlo" class=""> case let double as Double:</font></div><div class=""><font face="Menlo" class=""> try container.encode(double, forKey: DynamicCodingKeys(stringValue: key)!)</font></div><div class=""><font face="Menlo" class=""> case let string as String:</font></div><div class=""><font face="Menlo" class=""> try container.encode(string, forKey: DynamicCodingKeys(stringValue: key)!)</font></div><div class=""><font face="Menlo" class=""> default:</font></div><div class=""><font face="Menlo" class=""> fatalError("unexpected type")</font></div><div class=""><font face="Menlo" class=""> }</font></div><div class=""><font face="Menlo" class=""> }</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=""> private enum StaticCodingKeys: String, CodingKey {</font></div><div class=""><font face="Menlo" class=""> case id, email, name, metadata</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=""> private struct DynamicCodingKeys: CodingKey {</font></div><div class=""><font face="Menlo" class=""> var stringValue: String</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class=""> init?(stringValue: String) {</font></div><div class=""><font face="Menlo" class=""> self.stringValue = stringValue</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=""> var intValue: Int?</font></div><div class=""><font face="Menlo" class=""><br class=""></font></div><div class=""><font face="Menlo" class=""> init?(intValue: Int) {</font></div><div class=""><font face="Menlo" class=""> self.init(stringValue: "")</font></div><div class=""><font face="Menlo" class=""> self.intValue = intValue</font></div><div class=""><font face="Menlo" class=""> }</font></div><div class=""><font face="Menlo" class=""> }</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=""> {</font></div><div class=""><font face="Menlo" class=""> "id": "4yq6txdpfadhbaqnwp3",</font></div><div class=""><font face="Menlo" class=""> "email": "<a href="mailto:john.doe@example.com" class="">john.doe@example.com</a>",</font></div><div class=""><font face="Menlo" class=""> "name":"John Doe",</font></div><div class=""><font face="Menlo" class=""> "metadata": {</font></div><div class=""><font face="Menlo" class=""> "link_id": "linked-id",</font></div><div class=""><font face="Menlo" class=""> "buy_count": 4</font></div><div class=""><font face="Menlo" class=""> }</font></div><div class=""><font face="Menlo" class=""> }</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: 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="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><font face="Menlo" class="">// Prints: {"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="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;">-- </div><div class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;">Randy Eckenrode</div><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">_______________________________________________</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">swift-users mailing list</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><a href="mailto:swift-users@swift.org" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">swift-users@swift.org</a><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><a href="https://lists.swift.org/mailman/listinfo/swift-users" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;" class="">https://lists.swift.org/mailman/listinfo/swift-users</a></div></blockquote></div><br class=""></div></body></html>