Skip to content

Instantly share code, notes, and snippets.

@fcanas
Last active July 13, 2022 21:33
Show Gist options
  • Save fcanas/694c9e9caf151ff13d16 to your computer and use it in GitHub Desktop.
Save fcanas/694c9e9caf151ff13d16 to your computer and use it in GitHub Desktop.
JSON Serialization driven by Swift Reflection

A swift playground experiment in making a Swift struct to JSON serialization.

The approach currently fails for arrays, but those can be handled much like dictionaries and optionals.

//: Playground - noun: a place where people can play
struct PhoneNumber {
let countryCode :Int
let number :Int
}
struct Person {
let name :String
let phoneNumber :[String : PhoneNumber]
}
let jane = Person(name: "Jane Doe", phoneNumber: ["cell": PhoneNumber(countryCode: 1, number: 5555555)])
let jM = Mirror(reflecting: jane)
let pC = jM.children
for case let (label, value) in pC {
label
value
}
protocol JSON {
func asJSON() -> Any?
}
extension JSON {
func asJSON() -> Any? {
let mirror = Mirror(reflecting: self)
if mirror.children.count == 0 {
return self
}
var out: [String:Any] = [:]
for case let (key?, value) in mirror.children {
if let value = value as? JSON {
out[key] = value.asJSON()
}
}
return out
}
}
extension String :JSON {}
extension Int :JSON {}
extension Float :JSON {}
extension Bool :JSON {}
extension Optional :JSON {
func asJSON() -> Any? {
if let value = self as? JSON {
return value.asJSON
} else {
return nil
}
}
}
extension Dictionary :JSON {
func asJSON() -> Any? {
var out :[String: Any] = [:]
if Key.self == String.self {
for (key, value) in self {
out[key as! String] = value
}
}
return out
}
}
"hi".asJSON()
3.asJSON()
true.asJSON()
extension Person :JSON {}
extension PhoneNumber :JSON {}
let janeJSON = jane.asJSON()
(janeJSON as! [String:Any])["phoneNumber"]
["hi":5].asJSON()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment