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() |