json - 如何在 Realm 版本 10.15.0 中将数据转换为 Json
问题描述
在领域版本 10.7.1 中,它使用了此代码,但是当迁移到 10.15.0 时,它不再可能,因为 ListBase 类不再存在
extension Object {
func toWebServiceRequest() -> [String:AnyObject] {
let properties = self.objectSchema.properties.map { $0.name }
var dicProps = [String:AnyObject]()
for (key, value) in self.dictionaryWithValues(forKeys: properties) {
if let value = value as? ListBase {
dicProps[key] = value.toArray() as AnyObject
} else if let value = value as? Object {
dicProps[key] = value.toWebServiceRequest() as AnyObject
} else {
dicProps[key] = value as AnyObject
}
}
return dicProps
}
}
extension ListBase {
func toArray() -> [AnyObject] {
var _toArray = [AnyObject]()
for i in 0..<self._rlmArray.count {
let obj = unsafeBitCast(self._rlmArray[i], to: Object.self)
_toArray.append(obj.toWebServiceRequest() as AnyObject)
}
return _toArray
}
}
解决方案
mongo 团队希望您使用Codable
协议而不是一些自定义编码机制。这确实是正确的方法,否则您必须依赖Realm
实现细节。
class Parent: Object, Codable {
@Persisted var name: String = ""
@Persisted var children: List<Child>
convenience init(name: String, children: [Child] = []) {
self.init()
self.name = name
self.children.append(objectsIn: children)
}
}
如果服务器期望的键与您的对象的属性名称不同,您可以定义自定义 CodingKeys:
class Child: Object, Codable {
@Persisted var id: Int = 0
@Persisted var name: String = ""
enum CodingKeys: String, CodingKey {
case id = "_id"
case name = "name"
}
convenience init(id: Int, name: String) {
self.init()
self.id = id
self.name = name
}
}
用法很简单:
func makeParent() -> Parent {
Parent(name: "Alex", children: [
Child(id: 1, name: "Jim"),
Child(id: 2, name: "Tom"),
Child(id: 3, name: "Sam"),
Child(id: 4, name: "Joe"),
])
}
func encode<Item: Encodable>(_ item: Item) throws -> Data {
let encoder = JSONEncoder()
return try encoder.encode(item)
}
func convertDataToString(_ data: Data) throws -> String? {
return String(data: data, encoding: .utf8)
}
func decode<Item: Decodable>(_ type: Item.Type, from data: Data) throws -> Item {
let decoder = JSONDecoder()
return try decoder.decode(type, from: data)
}
func executeProgram() throws {
let parent = makeParent()
let encodedJSONData = try encode(parent)
guard let encodedJSONString = try convertDataToString(encodedJSONData) else {
throw Error.badJSON
}
print("JSON: \(encodedJSONString)")
let decodedParent = try decode(Parent.self, from: encodedJSONData)
print("Decoded Parent: \(decodedParent)")
}
在编码路线上,这会导致:
JSON: {"name":"Alex","children":[{"_id":1,"name":"Jim"},{"_id":2,"name":"Tom"},{" _id":3,"name":"Sam"},{"_id":4,"name":"Joe"}]}
在解码路线上,这会导致:
解码父级:父级 { name = Alex; 孩子 = 列表 <0x600000a2b800> ( [0] 孩子 { id = 1; 姓名 = Jim; }, [1] 孩子 { id = 2; 姓名 = 汤姆; }, [2] 孩子 { id = 3; 姓名 = Sam; }, [3] 孩子 { id = 4; 姓名 = 乔; } ); }
您显然可以省略String
转换,只使用结果Data
。
推荐阅读
- html - 子域可以在父域上设置cookie吗
- c# - C# - 通过用户输入值减去 int
- solr - Solr - 配置建议搜索子字符串
- unique - NestJS TypeORM - 为什么实体中的唯一约束会引发异常并使应用程序崩溃
- c# - 如何使用 C# 在另一台显示器 (HDMI) 中流式传输媒体文件?
- ssl-certificate - 握手失败,出现致命错误 SSL_ERROR_SSL: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed
- swift - 如何将 UITextView 添加到 UITableView 的底部
- swift - 运行后台定时器 Swift
- vue.js - 将 .env 文件与 vue.config.js 关联
- go - 当另一个对象告诉 Struct 更新时,Struct 字段不更新