如何在Swift中为Realm模型设置主键

44

我正在一个新的iOS Swift项目中使用Realm。我使用的是Xcode 6.0.1和iOS SDK 8.0以及Realm 0.85.0。

我尝试使用新的Realm主键功能,以便我可以执行addOrUpdateObject操作。

以下是一个示例模型:

import Foundation
import Realm

class Foo: RLMObject {
    dynamic var id = 0
    dynamic var title = ""

    func primaryKey() -> Int {
        return id
    }
}

我正在尝试添加/更新一个新对象:

let foo = Foo()
foo.title = titleField.text
foo.id = 1

// Get the default Realm
let realm = RLMRealm.defaultRealm()

// Add to the Realm inside a transaction
realm.beginWriteTransaction()
realm.addOrUpdateObject(foo)
realm.commitWriteTransaction()

我收到了这个错误:

RLMExecption',原因是:“'Foo'没有主键,无法更新

这里是有关主键的文档。 我可能没有正确设置它: http://realm.io/docs/cocoa/0.85.0/api/Classes/RLMObject.html#//api/name/primaryKey

最新的文档现在在这里: https://realm.io/docs/objc/latest/api/Classes/RLMObject.html#//api/name/primaryKey


1
无法访问realm.io文档的链接已损坏。 - Tyler
我们在推出Realm Swift时将我们的“cocoa”文档移到了“objc”,因此请尝试使用此链接:https://realm.io/docs/objc/latest/api/Classes/RLMObject.html#//api/name/primaryKey。我们正在设置重定向从旧链接,以便未来不会造成太多混淆。 - jpsim
旧链接到新文档的重定向似乎不起作用,因此我使用新链接更新了我的问题。 - jeffjv
4个回答

93

从Realm Swift v10.10.0开始,您可以使用@Persisted(primaryKey: true)来声明主键:

class Foo: Object {
    @Persisted(primaryKey: true) var id = 0
    @Persisted var title = ""
}

旧版本:

primaryKey 需要是一个类函数,它返回主键属性的名称,而不是一个实例方法,该方法返回主键的值。

@objcMembers class Foo: RLMObject {
    dynamic var id = 0
    dynamic var title = ""

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

谢谢,是的,这些都是我的问题。另外,为了让它正常工作,我需要添加“override”来覆盖声明。 - jeffjv
我已经更新了答案,包括Realm需要正确调用自定义类函数的“override”关键字。 - Glen Selle
由于某些原因,我收到了“无效的重新声明'primaryKey()'”错误。似乎找不出原因。 - Entalpi
1
@Entalpi 我更新了文档 http://realm.io/docs/cocoa/0.89.2/#customizing-models,请问你还看到任何错误吗?如果有的话,可以随时在 https://groups.google.com/forum/#!forum/realm-cocoa 上给我发消息,并附上你的代码示例。 - yoshyosh
根据@CherryKuczery的说法,返回类型是可选的。如果我有足够的声望,我会合并这两个答案。 - clozach

8
primaryKey()的返回类型是可选的:
class Foo: RLMObject {
    dynamic var id = 0
    dynamic var title = ""

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

谢谢您添加这个,看起来接受的答案也改变了以反映可选的返回类型。 - Ethan Parker

8

针对 Swift 5:

import RealmSwift

     class Signature: Object {

           @objc dynamic var id = ""

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

避免:未捕获异常引起的应用程序终止,原因是对象上不存在主键属性'id'。

这个答案救了我的一天!非常感谢! - dcg

1

Realm 10.12.0 & Swift 5

使用@objc进行遗留属性声明:

import RealmSwift

class Signature: Object {
    @objc dynamic var id = ""

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

在使用@Persisted时,请使用@Persisted(primaryKey:true)代替:

import Foundation
import RealmSwift

class MyModel: Object {
    @Persisted var pan: String?
    @Persisted var exp: String?
    @Persisted var cvv: String?
    @Persisted(primaryKey: true) var myId: String?
    
    override init() {}
    
    init(pan: String, exp: String, cvv2: String) {
        super.init()
        self.pan = pan
        self.exp = exp
        self.cvv = cvv2
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接