如何在 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 中将 CMSampleBuffer 转换为数据?