Skip to content

Instantly share code, notes, and snippets.

@anaimi
Created July 9, 2014 03:51
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save anaimi/ad336b44d718430195f8 to your computer and use it in GitHub Desktop.
Save anaimi/ad336b44d718430195f8 to your computer and use it in GitHub Desktop.
Serialize a Swift object to JSON or Dictionary, with selective properties.
/*
Purpose:
Convert (or Serialize) an object to a JSON String or Dictionary.
Usage:
Use 'Serialize.toJSON' on instances of classes that:
- Inherit from NSObject
- Implement 'Serializable' protocol
- Implement the property 'jsonProperties' and return an array of strings with names of all the properties to be serialized
Inspiration/Alternative:
https://gist.github.com/turowicz/e7746a9c035356f9483d
*/
import Foundation
@objc protocol Serializable {
var jsonProperties:Array<String> { get }
func valueForKey(key: String!) -> AnyObject!
}
struct Serialize {
static func toDictionary(obj:Serializable) -> NSDictionary {
// make dictionary
var dict = Dictionary<String, AnyObject>()
// add values
for prop in obj.jsonProperties {
var val:AnyObject! = obj.valueForKey(prop)
if (val is String)
{
dict[prop] = val as String
}
else if (val is Int)
{
dict[prop] = val as Int
}
else if (val is Double)
{
dict[prop] = val as Double
}
else if (val is Array<String>)
{
dict[prop] = val as Array<String>
}
else if (val is Serializable)
{
dict[prop] = toJSON(val as Serializable)
}
else if (val is Array<Serializable>)
{
var arr = Array<NSDictionary>()
for item in (val as Array<Serializable>) {
arr.append(toDictionary(item))
}
dict[prop] = arr
}
}
// return dict
return dict
}
static func toJSON(obj:Serializable) -> String {
// get dict
var dict = toDictionary(obj)
// make JSON
var error:NSError?
var data = NSJSONSerialization.dataWithJSONObject(dict, options:NSJSONWritingOptions(0), error: &error)
// return result
return NSString(data: data, encoding: NSUTF8StringEncoding)
}
}
@tonglil
Copy link

tonglil commented Aug 12, 2014

Do you have a usage example? Not sure how to implement the protocol's property and method.

@ziogaschr
Copy link

Here you can find an example.

class Person {
    var name: String?
    var ignoreThisVar: Int?

    init() {}

    func descriptionInJSON() {
        return Serialize.toJSON(self)
    }
}
extension Person: Serializable {
    var jsonProperties:Array<String> {
        get {
            return ["name"]
        }
    }
    func valueForKey(key: String!) -> AnyObject! {
        if key == "name" {
            return self.name
        }
        return nil
    }
}

var person1 = Person()
println(person1.descriptionInJSON())

@Blackjacx
Copy link

Hi,

why this:

let expected = "{\"sum\":{\"currency\":\"EUR\",\"amount\":\"24,95\"},\"period\":\"August 2014\"}"
let data = expected.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
let json = JSON(data: data!, error: nil)
let billsummary = BillSummary(json: json)
let serialized = Serialize.toJSON(billsummary)
let deserialized = BillSummary(json: JSON(data: serialized.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, error: nil))

prefixes my nested object properties with 3 back slashes:

serialized = "{\"sum\":\"{\\\"currency\\\":\\\"EUR\\\",\\\"amount\\\":\\\"24,95\\\"}\",\"period\":\"August 2014\"}"

It should look like in expected

@croccio
Copy link

croccio commented Sep 15, 2015

please change line 50 so

dict[prop] = toDictionary(val as Serializable)

as your way do cannot create son of need object

@michzio
Copy link

michzio commented Sep 22, 2019

Maybe better will be to use JSONEncoder.encode() Then JSONSerialization.jsonObject() ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment