swift JSON和Realm -我必须维护单独的结构体/类吗?

3phpmpom  于 2023-01-29  发布在  Swift
关注(0)|答案(1)|浏览(106)

当我从API调用中接收JSON时,在解码它时,我会使用如下结构:

import Foundation

struct JSON: Codable {
    
    var alpha: Alpha
    var beta: Beta
    var gamma: [Gamma]?
    
}

我想把JSON保存在Realm数据库中,以便以后像JSON一样使用和遍历。我的理解是,我不能只使用我编写的现有结构体,而是必须重写第二个(类似的)类,以便与Realm一起使用:

import Foundation
import RealmSwift

class RealmJSON: Object, Identifiable {
    
    @Persisted (primaryKey: true) var id: ObjectId
    
    @Persisted var alpha: RealmAlpha
    @Persisted var beta: RealmBeta
    @Persisted var gamma: RealmSwift.List<RealmGamma>?
    
    override class func primaryKey() -> String? {
        "id"
    }
    
    convenience init(id: ObjectId, alpha: RealmAlpha, beta: RealmBeta, gamma: RealmSwift.List<RealmGamma>?) {
        
        self.init()
        
        self.id = id
        self.alpha = alpha
        self.beta = beta
        self.gamma = gamma
    }
    
}

显然,这是不方便的,尤其是在处理大量JSON时。此外,我想使用Swagger codegen为我编写客户端代码,但如果我必须手动添加Realm类,这就有点违背了目的。
这是处理JSON和Realm数据库的唯一方法吗?还是我在这里遗漏了什么?
编辑:我意识到一个简单的方法是将大部分JSON存储为一个原始JSON字符串,并带有标识模式类型/版本的属性。然后,我可以获取所需的正确模式,并使用现有的JSON结构体解析原始JSON字符串...

ngynwnxp

ngynwnxp1#

您可以将JSON数据直接传递给您的对象。我可以想到两种方法。
第一种方法,符合Codable

class Dog: Object, Codable {
    @Persisted var name: String
}

class Cat: Object, Codable {
    @Persisted var name: String
}

class Kid: Object, Codable {
    @Persisted var name: String
}

class Owner: Object, Codable {
    @Persisted var name: String
    @Persisted var dog: Dog?
    @Persisted var cat: Cat?
    @Persisted var kids: List<Kid>
}

让我们使用下面的方法来制作json数据:

func makeData() -> Data {
    let string = """
        {
            "name": "Tom",
            "kids": [{"name": "Penelope"}, {"name": "Rob"}],
            "cat": {"name": "Lilly"},
            "dog": {"name": "Lucy"}
        }
    """
    return string.data(using: .utf8)!
}

现在我们可以创建对象了:

func decodeOwner() {
    let decoder = JSONDecoder()
    let owner = try! decoder.decode(Owner.self, from: makeData())
    print("Decoded:", owner)
}

另一种方法是使用JSONSerialization并将结果传递给值构造函数:

extension Object {
    convenience init(json: Data) throws {
        let data = try JSONSerialization.jsonObject(with: json)
        self.init(value: data)
    }
}

func serializeOwner() {
    let owner = try! Owner(json: makeData())
    print("Serialization:", owner)
}

相关问题