Skip to content

Instantly share code, notes, and snippets.

@stinger
Last active May 26, 2023 10:58
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save stinger/803299c1ee0c95e53dc3d9e59c37b187 to your computer and use it in GitHub Desktop.
Save stinger/803299c1ee0c95e53dc3d9e59c37b187 to your computer and use it in GitHub Desktop.
Swift 3: JSON-serializable structs using protocols
//: # Swift 3: JSON-serializable structs using protocols
//: Most of the implementation is based on the code in [this blog post](http://codelle.com/blog/2016/5/an-easy-way-to-convert-swift-structs-to-json/)
import Foundation
//: ### Defining the protocols
protocol JSONRepresentable {
var JSONRepresentation: Any { get }
}
protocol JSONSerializable: JSONRepresentable {}
//: ### Implementing the functionality through protocol extensions
extension JSONSerializable {
var JSONRepresentation: Any {
var representation = [String: Any]()
for case let (label?, value) in Mirror(reflecting: self).children {
switch value {
case let value as Dictionary<String, Any>:
representation[label] = value as AnyObject
case let value as Array<Any>:
if let val = value as? [JSONSerializable] {
representation[label] = val.map({ $0.JSONRepresentation as AnyObject }) as AnyObject
} else {
representation[label] = value as AnyObject
}
case let value:
representation[label] = value as AnyObject
default:
// Ignore any unserializable properties
break
}
}
return representation as Any
}
}
extension JSONSerializable {
func toJSON() -> String? {
let representation = JSONRepresentation
guard JSONSerialization.isValidJSONObject(representation) else {
print("Invalid JSON Representation")
return nil
}
do {
let data = try JSONSerialization.data(withJSONObject: representation, options: [])
return String(data: data, encoding: .utf8)
} catch {
return nil
}
}
}
//: ### Define the Structures
//: Notice how they are conforming to the `JSONSerializable` protocol
struct Author: JSONSerializable {
var name: String
}
struct Book: JSONSerializable {
var title: String
var isbn: String
var pages: Int
var authors:[JSONSerializable]
var extra:[String: Any]
}
//: ### Create a sample object for serialization
let book = Book(
title: "Mirage",
isbn: "0399158081",
pages: 397,
authors: [
Author(name: "Clive Cussler"),
Author(name:"Jack Du Brul")
],
extra: [
"foo": "bar",
"baz": 142.226
]
)
//: ### Use the protocols to convert the data to JSON
if let json = book.toJSON() {
print(json)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment