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

Posted

技术标签:

【中文标题】如何在 Realm 版本 10.15.0 中将数据转换为 Json【英文标题】:How convert data to Json in Realm version 10.15.0 【发布时间】:2021-11-17 08:33:02 【问题描述】:

在领域版本 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
    


【问题讨论】:

【参考方案1】:

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)
    

如果服务器期望的键与您的对象的属性名称不同,您可以定义自定义 CodingKey:

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;孩子=列表 ([0] 孩子 id = 1; 名字 = Jim; , [1] 孩子 id = 2;名字=汤姆; , [2] 孩子 id = 3; 名字=山姆; , [3] 孩子 id = 4;名字=乔; );

您显然可以省略String 转换,只使用生成的Data

【讨论】:

以上是关于如何在 Realm 版本 10.15.0 中将数据转换为 Json的主要内容,如果未能解决你的问题,请参考以下文章

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

Realm (Swift):如何在迁移期间获取 MutableSet 数据?

使用新版Realm的应用程序无法打开使用旧版Realm的应用程序创建的DB。

Android Realm数据库使用

Android Realm 详解

如何在 Xcode 4 中将数据模型转换为版本化数据模型?