如何将 Realm 对象转换为 Swift 中的 JSON?

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

我声明了两个领域表:

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

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

最终目标是将 Task Realm 对象转换为 JSON。我想到的方法是:

使用 class

中的方法将对象转换为字典
func taskToDictionary() -> [String: AnyObject] {
    return [
        "taskID" : self.taskID,
        "taskAssignedTo" : self.taskAssignedTo._rlmArray.count //Not sure how to get the array
    ]
}

使用 SwiftyJSON

将生成的字典转换为 JSON
let taskObject = Task()
let newTaskJSON = JSON(taskObject.taskToDictionary())

现在,转换正常,但是:

  1. 有更好的方法吗?
  2. 如何将 RLMArray 转换为数组以进行 JSON 转换?

设法在这里找到答案:

extension Object {
func toDictionary() -> NSDictionary {
    let properties = self.objectSchema.properties.map { [=10=].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
}
}

Xcode 7 和 Swift 2 的更新:

extension Object {
func toDictionary() -> NSDictionary {
    let properties = self.objectSchema.properties.map { [=11=].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
}

}

更新到 Xcode 8 和 Swift 3 :

extension Object {
func toDictionary() -> NSDictionary {
    let properties = self.objectSchema.properties.map { [=12=].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
}
}

由于我无法发表评论,@Eric

基于@Eugene Teh 的回答 我必须对日期进行特定处理。这是我的代码 (swift 3)

我先取值

if  let value = self.value(forKey: props.name) {
    if props.type == .date {
        mutabledic[props.name] = (value as! Date).timeIntervalSince1970
        //for using like the example, this should work
        //mutabledic.setObject( (value as! Date).timeIntervalSince1970, forKey: prop.name as NSCopying)
    }
    [..]//other case
}

Swift 4.2 Xcode 11

这就是我解决问题的方法。将 Realm 对象转换为 JSON 数组以发送到 Rest API 要求 - SwiftyJSON

func getJsonArray(){
        var dicArray = [Dictionary<String,AnyObject>]()
        for item in cartsData! {
             dicArray.append(item.toDictionary())
        }
        print(JSON(dicArray))
    }

cartsData - var cartsData:结果<...>?

extension Object {
    func toDictionary() -> [String:AnyObject] {
        let properties = self.objectSchema.properties.map { [=11=].name }
        var dicProps = [String:AnyObject]()
        for (key, value) in self.dictionaryWithValues(forKeys: properties) {
            //key = key.uppercased()
            if let value = value as? ListBase {
                dicProps[key] = value.toArray1() as AnyObject
            } else if let value = value as? Object {
                dicProps[key] = value.toDictionary() as AnyObject
            } else {
                dicProps[key] = value as AnyObject
            }
        }
        return dicProps
    }
}

extension ListBase {
    func toArray1() -> [AnyObject] {
        var _toArray = [AnyObject]()
        for i in 0..<self._rlmArray.count {
            let obj = unsafeBitCast(self._rlmArray[i], to: Object.self)
            _toArray.append(obj.toDictionary() as AnyObject)
        }
        return _toArray
    }
}