更改 Realm Swift 对象模型上的主键 属性 名称

Changing primary key property name on Realm Swift object model

我有一个 Realm (Swift) 对象,它在我的应用程序中已经存在了大约一年。该对象的模型如下所示:

class ChatMessage: Object {

    @objc dynamic var messageId: Int = generateId()
    // other properties omitted

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

现在,我发现自己需要有效地将“messageId”属性 重命名为“id”并使“id”成为主键。我需要这样做,因为我需要此对象符合特定协议(来自我无法控制的框架),并且该协议指定我需要字符串类型的“messageId”属性。重命名似乎是对我正在尝试做的事情最直接的解释,但我意识到这也可以通过说我想要来解释:

  1. 创建一个新的“id”属性(Int 类型)
  2. 将“messageId”的现有值复制到“id”属性(迁移期间)
  3. 更改主键以使用“id”而不是“messageId”

实际上,我希望对象在更改后的样子是:

class ChatMessage: Object {

    @objc dynamic var id: Int = generateId()
    // other properties omitted

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

我定义了一个迁移块,并且尝试了几种不同的方法来完成此操作,但到目前为止还没有成功。没有迁移块,我在 Xcode 调试控制台中得到以下信息:

ERROR - Failed to open Realm! Error Domain=io.realm Code=10 "Migration is required due to the following errors:
- Property 'ChatMessage.messageId' has been removed.
- Property 'ChatMessage.id' has been added.
- Primary Key for class 'ChatMessage' has changed from 'messageId' to 'id'.

为了它的价值,我使用的是 Realm 5.50,我已经通读了 https://realm.io/docs/swift/latest/ 上的文档,我看到了这个声明:

Once an object with a primary key is added to a Realm, the primary key cannot be changed.

这听起来好像无法再使用 Realm,但我想知道是否有人可以确认这一点,或者实际上是否有实现此目的的方法?谢谢!

您实际上可以在迁移块中更改主键。假设你有一个看起来像这样的对象,其中 'localID' 是主键

class TestClass: Object {
    @objc dynamic var localID = UUID().uuidString

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

并且我们想将主键更改为 _id。迁移块看起来像这样

let vers = UInt64(3)
let config = Realm.Configuration( schemaVersion: vers, migrationBlock: { migration, oldSchemaVersion in
     print("oldSchemaVersion: \(oldSchemaVersion)")
     if (oldSchemaVersion < vers) {
        print("  performing migration")
        migration.enumerateObjects(ofType: TestClass.className()) { oldItem, newItem in
            let oldId = oldItem!["localID"]
            newItem!["_id"] = oldId

         }
     }
 })

我建议使用 _id 而不是 id 以便将来与 MongoDB Realm 兼容。 See Define a Realm Schema