Last active
November 8, 2017 07:44
-
-
Save monkeywithacupcake/ab1a204f12186a11b28d8554b287cde0 to your computer and use it in GitHub Desktop.
Dealing with nested JSON with dynamic keys
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//: Playground - noun: a place where people can play | |
import UIKit | |
import Foundation | |
struct Thing: Decodable { | |
let id: String | |
let isActive: Bool | |
let name: String | |
let owner: String | |
//var cases = [Case]() | |
init(id: String, isActive: Bool, name: String, owner: String){//}, cases: [Case]?) { | |
self.id = id | |
self.isActive = isActive | |
self.name = name | |
self.owner = owner | |
//self.cases = cases ?? [Case(id: "none", caseNumber: 0)] | |
} | |
} | |
struct User: Decodable { | |
let id: String | |
let name: String | |
} | |
struct Case: Decodable { | |
let id: String | |
let caseNumber: Int | |
} | |
struct ResponseData: Decodable { | |
var things = [Thing]() | |
var users = [User]() | |
enum CodingKeys: String, CodingKey { | |
case trips | |
case users | |
} | |
private struct PhantomKeys: CodingKey { | |
var intValue: Int? | |
var stringValue: String | |
init?(intValue: Int) { self.intValue = intValue; self.stringValue = "\(intValue)" } | |
init?(stringValue: String) { self.stringValue = stringValue } | |
} | |
private enum ThingKeys: String, CodingKey { | |
case isActive, name, owner, cases | |
} | |
private enum UserKeys: String, CodingKey { | |
case name | |
} | |
private enum CaseKeys: String, CodingKey { | |
case id | |
case caseNumber = "no" | |
} | |
init(from decoder: Decoder) throws { | |
let outer = try decoder.container(keyedBy: CodingKeys.self) | |
let thingcontainer = try outer.nestedContainer(keyedBy: PhantomKeys.self, forKey: .things) | |
for key in thingcontainer.allKeys { | |
let aux = try thingcontainer.nestedContainer(keyedBy: ThingKeys.self, forKey: key) | |
let name = try aux.decode(String.self, forKey: .name) | |
let owner = try aux.decode(String.self, forKey: .owner) | |
let isActive = try aux.decode(Bool.self, forKey: .isActive) | |
// let c = try aux.nestedContainer(keyedBy: CaseKeys.self, forKey: .cases) | |
// var cases = [Case]() | |
// for ckey in c.allKeys { | |
// let caseNumber = try c.decode(Int.self, forKey: .caseNumber) | |
// let thiscase = Case(id: ckey.stringValue, caseNumber: caseNumber) | |
// cases.append(thiscase) | |
// } | |
let thing = Thing(id: key.stringValue, isActive: isActive, name: name, owner: owner)//, cases: cases) | |
things.append(thing) | |
} | |
let usercontainer = try outer.nestedContainer(keyedBy: PhantomKeys.self, forKey: .users) | |
for key in usercontainer.allKeys { | |
let aux = try usercontainer.nestedContainer(keyedBy: UserKeys.self, forKey: key) | |
let name = try aux.decode(String.self, forKey: .name) | |
let user = User(id: key.stringValue,name: name) | |
users.append(user) | |
} | |
} | |
} | |
let json = """ | |
{ | |
"things" : { | |
"123" : { | |
"name" : "Party", | |
"owner" : "Bob", | |
"isActive" : true, | |
"cases" : { | |
"case1" : { | |
"no" : 1 | |
}, | |
"case2" : { | |
"no" : 2 | |
} | |
} | |
}, | |
"456" : { | |
"name" : "Bus", | |
"owner" : "Joe", | |
"isActive" : true | |
} | |
}, | |
"users" : { | |
"u1" : { | |
"name" : "Summer" | |
}, | |
"u2" : { | |
"name" : "Daffy" | |
} | |
} | |
} | |
""" | |
let data = json.data(using: .utf8)! | |
let things = try JSONDecoder().decode(ResponseData.self, from: data).things | |
print(things[0]) | |
//Thing(id: "456", isActive: true, name: "Bus", owner: "Joe") | |
let users = try JSONDecoder().decode(ResponseData.self, from: data).users | |
print(users[0]) | |
//User(id: "u1", name: "Summer") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment