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