【问题标题】:How convert data to Json in Realm version 10.15.0如何在 Realm 版本 10.15.0 中将数据转换为 Json
【发布时间】: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
    }
}

【问题讨论】:

    标签: json swift object realm


    【解决方案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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-27
      • 2018-07-26
      • 2022-07-13
      • 2017-05-25
      • 1970-01-01
      相关资源
      最近更新 更多