Search code examples
jsonswiftrealm

How can I convert a Realm object to JSON in Swift?


I have two Realm tables declared:

class Task: Object {
    dynamic var taskID: String = ""
    let taskAssignedTo = List<Contacts>()
}

class Contacts: Object {
    dynamic var contactEmail: String = ""
    dynamic var contactName: String = ""
}

Final goal is to convert the Task Realm object into JSON. The method I'm thinking of is:

Convert the object to a dictionary using a method within the class

func taskToDictionary() -> [String: AnyObject] {
    return [
        "taskID" : self.taskID,
        "taskAssignedTo" : self.taskAssignedTo._rlmArray.count //Not sure how to get the array
    ]
}

Convert the resulting dictionary into JSON with SwiftyJSON

let taskObject = Task()
let newTaskJSON = JSON(taskObject.taskToDictionary())

Right now, this converts ok, but:

  1. Is there a better way to do this?
  2. How can I convert the RLMArray into an array for JSON conversion?

Solution

  • Managed to find the answer here:

    Can I serialize a RealmObject to JSON or to NSDictionary in Realm for Swift?

    extension Object {
    func toDictionary() -> NSDictionary {
        let properties = self.objectSchema.properties.map { $0.name }
        let dictionary = self.dictionaryWithValuesForKeys(properties)
    
        var mutabledic = NSMutableDictionary()
        mutabledic.setValuesForKeysWithDictionary(dictionary)
    
        for prop in self.objectSchema.properties as [Property]! {
            // find lists
            if let objectClassName = prop.objectClassName  {
                if let nestedObject = self[prop.name] as? Object {
                    mutabledic.setValue(nestedObject.toDictionary(), forKey: prop.name)
                } else if let nestedListObject = self[prop.name] as? ListBase {
                    var objects = [AnyObject]()
                    for index in 0..<nestedListObject._rlmArray.count  {
                        if let object = nestedListObject._rlmArray[index] as? Object {
                            objects.append(object.toDictionary())
                        }
                    }
                    mutabledic.setObject(objects, forKey: prop.name)
                }
            }
        }
        return mutabledic
    }
    }
    

    Update for Xcode 7 & Swift 2:

    extension Object {
    func toDictionary() -> NSDictionary {
        let properties = self.objectSchema.properties.map { $0.name }
        let dictionary = self.dictionaryWithValuesForKeys(properties)
    
        let mutabledic = NSMutableDictionary()
        mutabledic.setValuesForKeysWithDictionary(dictionary)
    
        for prop in self.objectSchema.properties as [Property]! {
            // find lists
            if let nestedObject = self[prop.name] as? Object {
                mutabledic.setValue(nestedObject.toDictionary(), forKey: prop.name)
            } else if let nestedListObject = self[prop.name] as? ListBase {
                var objects = [AnyObject]()
                for index in 0..<nestedListObject._rlmArray.count  {
                    let object = nestedListObject._rlmArray[index] as AnyObject
                    objects.append(object.toDictionary())
                }
                mutabledic.setObject(objects, forKey: prop.name)
            }
    
        }
        return mutabledic
    }
    
    }
    

    Update to Xcode 8 and Swift 3 :

    extension Object {
    func toDictionary() -> NSDictionary {
        let properties = self.objectSchema.properties.map { $0.name }
        let dictionary = self.dictionaryWithValues(forKeys: properties)
        let mutabledic = NSMutableDictionary()
        mutabledic.setValuesForKeys(dictionary)
    
        for prop in self.objectSchema.properties as [Property]! {
            // find lists
            if let nestedObject = self[prop.name] as? Object {
                mutabledic.setValue(nestedObject.toDictionary(), forKey: prop.name)
            } else if let nestedListObject = self[prop.name] as? ListBase {
                var objects = [AnyObject]()
                for index in 0..<nestedListObject._rlmArray.count  {
                    let object = nestedListObject._rlmArray[index] as AnyObject
                    objects.append(object.toDictionary())
                }
                mutabledic.setObject(objects, forKey: prop.name as NSCopying)
            }
        }
        return mutabledic
    }
    }