领域:@Persisted(primaryKey: bool) 从 static func PrimaryKey() 迁移

问题描述 投票:0回答:1

我正在从 Realm 对象中删除所有

@objc dynamic
注释,以使用更现代的
@Persisted
注释。

虽然它对很多代码都有好处,但我遇到了问题,其中之一与对象主键相关。 这是文档。让我们举个例子:

class MyObject: Object {
    
    @objc public dynamic var uuid = ""

    // many other properties...

    override public static func primaryKey() -> String? {
        "uuid"
    }
}

这会变成这样:

class MyObject: Object {
    @Persisted(primaryKey: true) @objc public var uuid: String
}

但是运行测试会输出此错误:

Error Domain=io.realm Code=10 "Migration is required due to the following errors:
- Primary Key for class 'MyObject' has been removed." UserInfo={Error Name=SchemaMismatch, NSLocalizedDescription=Migration is required due to the following errors:
- Primary Key for class 'MyObject' has been removed., Error Code=10}

注 1:需要

@objc
注释,因为该属性是从 Objective-C 代码访问的。我也在没有
@objc
注释的情况下测试了这个案例,结果是一样的。根据此问题/答案,这是可能的。

注 2:在这两种情况下(之前/之后),

uuid
都是这样初始化的:

override public required init() {
    super.init()

    let uuid = UUID().uuidString
}

这可能是因为架构中相关对象中存在另一个问题吗?比如我已经“翻译”了

    @objc public private(set) dynamic var id: Int = 1

    public var categoryList = List<PersistableIdentifiableObject>()

    override public required init() {
        super.init()
    }

    override public class func primaryKey() -> String? {
        #keyPath(MyObject.id)
    }

    @Persisted(primaryKey: true) public private(set) var id: Int

    @Persisted public var categoryList = List<PersistableIdentifiableObject>()

    override public required init() {
        super.init()
        id = 1 // Yes, this is meant to be this way.
    }

感谢您对此提供的任何帮助。

swift realm
1个回答
0
投票

问题中的代码有一些问题,但让我尝试一下解释和答案。

所以这行不通

override public static func primaryKey() -> String? {
   "uuid"
}

因为需要返回“uuid”,就像这样

override public static func primaryKey() -> String? {
   return "uuid"
}

还要注意,在上面的例子中,primaryKey是一个String?所以让它成为一个 Int 工作

@Persisted(primaryKey: true) public private(set) var id: Int

并且不要对 Realm 对象执行此操作,因为它们需要方便的初始化,而不是覆盖。

override public required init() {
   super.init()

--

现在 - 解决问题:

回到 @objc 的时代,这里是如何定义具有主键的对象。

class Dog: Object {
    @objc dynamic var id = ""
    override static func primaryKey() -> String? {
        return "id"
    }
}

请注意,primaryKey 函数返回主键属性的 name(不是它的值)并且是 可选

现在我们做同样的事情,确保它仍然是一个可选字符串。这将从 @obc 流到 Swift,无需迁移(假设属性相同)

class Dog: Object {
    @Persisted(primaryKey: true) var id: String?
}

如果你希望主键是一个int,并且每次都初始化为1,代码如下

@Persisted(primaryKey: true) var id = 1

如果您想在实例化时使用提供的值初始化 Realm 对象,请在方便的 init 中执行此操作,确保调用 self.init 以让 Realm 将该对象初始化为 Realm 对象

class Dog: Object {
    @Persisted(primaryKey: true) var _id: ObjectId
    @Persisted var name = ""

    convenience init(withName: String) {
        self.init()
        self.name = withName
    }
}

然后

let dog = Dog(withName: "Spot")
© www.soinside.com 2019 - 2024. All rights reserved.