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

Posted

技术标签:

【中文标题】如何在 Swift 中将 Realm 对象转换为 JSON?【英文标题】:How can I convert a Realm object to JSON in Swift? 【发布时间】:2015-08-15 09:05:57 【问题描述】:

我声明了两个 Realm 表:

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。我想到的方法是:

使用类中的方法将对象转换为字典

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

现在,这可以转换,但是:

    有没有更好的方法来做到这一点? 如何将 RLMArray 转换为数组以进行 JSON 转换?

【问题讨论】:

【参考方案1】:

设法在这里找到答案:

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


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



更新到 Xcode 8 和 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


【讨论】:

似乎此扩展不适用于对象中的 NSDate 动态 var:*** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“JSON 写入 (_SwiftValue) 中的类型无效”* ** 任何人都知道如何避免这种情况? @Eric 将 nsDate 转换为 int64【参考方案2】:

因为我不能评论,@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

【讨论】:

只是一个快速的事情,得到你应该做的价值:让 value = mutabledic.value(forKey: prop.name) 这很好,但是你将很难从 JSON 中重建对象,因为 Realm 会尝试将 Int 转换为 Date【参考方案3】:

斯威夫特 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  $0.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
    

【讨论】:

以上是关于如何在 Swift 中将 Realm 对象转换为 JSON?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Realm 版本 10.15.0 中将数据转换为 Json

如何在 Swift 5 中将文档转换为自定义对象?

如何在 Swift 5 中将“日期”转换为“数据”,反之亦然? [复制]

如何在 Swift 中将 CMSampleBuffer 转换为数据?

如何在 Swift 2.0 中将 HKQuanity 转换为 Int

如何在 Swift 2.0 中将 HKQuanity 转换为 Int