Skip to content

Instantly share code, notes, and snippets.

@michaelevensen
Last active March 21, 2023 08:56
Show Gist options
  • Save michaelevensen/5df4ea4cd7b9d24d93a32d8ee3cc8995 to your computer and use it in GitHub Desktop.
Save michaelevensen/5df4ea4cd7b9d24d93a32d8ee3cc8995 to your computer and use it in GitHub Desktop.
Custom encoding and decoding of JSON data. Wouldn't necessary recommend this as your models should mirror your API.
import Swift
import Foundation
let json = """
{
"amount": 3,
"confirmed": false,
"context": {
"wishlist": {
"mTy7R1Y7OI22w1jAqKvo": {
"id": "12345",
"confirmed": true
}
},
"wish": {
"mTy7R1Y7OI22w1jAqKvo": {
"id": "12345",
"confirmed": true
}
}
}
}
"""
struct Wish: Codable {
let id: String?
let confirmed: Bool
}
struct Wishlist: Codable {
let id: String?
let confirmed: Bool
}
struct CodableObject: Codable {
let amount: Int
let confirmed: Bool
let context: Context
struct Context: Codable {
let wishlist: Wishlist
let wish: Wish
init(wishlist: Wishlist, wish: Wish) {
self.wishlist = wishlist
self.wish = wish
}
struct DynamicKeys: CodingKey {
var stringValue: String
init?(stringValue: String) {
self.stringValue = stringValue
}
var intValue: Int? { return nil }
init?(intValue: Int) { return nil }
static let wishlist = DynamicKeys(stringValue: "wishlist")!
static let wish = DynamicKeys(stringValue: "wish")!
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: DynamicKeys.self)
if let wishlistId = wishlist.id {
try container.encode([wishlistId: wishlist], forKey: DynamicKeys.wishlist)
}
if let wishId = wish.id {
try container.encode([wishId: wish], forKey: DynamicKeys.wish)
}
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: DynamicKeys.self)
var wishlistValueDict: [String: Wishlist]?
var wishValueDict: [String: Wish]?
for key in container.allKeys {
switch key.stringValue {
case DynamicKeys.wishlist.stringValue:
wishlistValueDict = try container.decode([String: Wishlist].self, forKey: key)
case DynamicKeys.wish.stringValue:
wishValueDict = try container.decode([String: Wish].self, forKey: key)
default:
throw NSError(domain: "Keys not found", code: 0, userInfo: nil)
}
}
guard let wishlist = wishlistValueDict?.values.first,
let wish = wishValueDict?.values.first else {
throw NSError(domain: "Could not decode keys", code: 0, userInfo: nil)
}
self.wish = wish
self.wishlist = wishlist
}
}
}
let object = CodableObject(amount: 3, confirmed: true, context: CodableObject.Context(wishlist: Wishlist(id: "234870982314782347", confirmed: true), wish: Wish(id: "83217409872139847", confirmed: false)))
let encoder = JSONEncoder()
if let json = try? encoder.encode(object) {
print(String(data: json, encoding: .utf8)!)
do {
let results = try JSONDecoder().decode(CodableObject.self, from: json)
print(results.context.wish.id)
print(results.context.wishlist.id)
} catch {
print(error)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment