Created
October 19, 2019 13:45
-
-
Save bparol/2edc83fe3e64e7035befbe2c28ed3be6 to your computer and use it in GitHub Desktop.
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
import UIKit | |
struct ComplexObject: Decodable { | |
let timestamp: Int | |
let identifier: String | |
} | |
extension ComplexObject { | |
enum CodingKeys: String, CodingKey { | |
case timestamp | |
case identifier | |
} | |
} | |
enum DecodingError: Error { | |
case corruptedData | |
} | |
enum ValueType: Decodable { | |
case number(Int) | |
case string(String) | |
case object(ComplexObject) | |
init(from decoder: Decoder) throws { | |
// 1 | |
do { | |
let singleValueContainer = try decoder.singleValueContainer() | |
let timestamp = try singleValueContainer.decode(Int.self) | |
self = .number(timestamp) | |
return | |
} catch {} | |
// 2 | |
do { | |
let singleValueContainer = try decoder.singleValueContainer() | |
let timestamp = try singleValueContainer.decode(String.self) | |
self = .string(timestamp) | |
return | |
} catch {} | |
// 3 | |
do { | |
let keyedContainer = try decoder.container(keyedBy: ComplexObject.CodingKeys.self) | |
let timestamp = try keyedContainer.decode(Int.self, forKey: .timestamp) | |
let identifier = try keyedContainer.decode(String.self, forKey: .identifier) | |
self = .object(ComplexObject(timestamp: timestamp, identifier: identifier)) | |
return | |
} catch {} | |
// 4 | |
throw DecodingError.corruptedData | |
} | |
} | |
typealias Values = [String: ValueType] | |
// Test | |
let json = """ | |
{ | |
"TjOnekTbvbh7XW7aTgEiyr2pccq1": 1565244404531, | |
"Zu9ujNWUi0fSz3Y8pNFJ8PV4Phk1": "some string value", | |
"AC5cZbp4XyPJfTu4zf9TfRQWRY02": { | |
"timestamp": 1566474347575, | |
"identifier": "Cu9BjNKU407Sz3Y8pNFJ8P64Phk1" | |
} | |
} | |
""" | |
if let jsonData = json.data(using: .utf8) { | |
let events = try JSONDecoder().decode(Values.self, from: jsonData) | |
for (key, eventData) in events { | |
switch eventData { | |
case ValueType.number(let timestamp): | |
print("It's a number! \(timestamp)") | |
case ValueType.string(let timestamp): | |
print("It's a string! \(timestamp)") | |
case ValueType.object(let timestamp): | |
print("It's an object! \(timestamp)") | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment