'How to set primary key in Swift for Realm model
I'm using Realm in a new iOS Swift project. I'm using Xcode 6.0.1 with iOS SDK 8.0 and Realm 0.85.0
I'm trying to use the new Realm primary key feature so I can do an addOrUpdateObject.
Here is a sample model:
import Foundation
import Realm
class Foo: RLMObject {
dynamic var id = 0
dynamic var title = ""
func primaryKey() -> Int {
return id
}
}
And how I'm trying to add/update a new object:
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()
I get this error:
RLMExecption', reason: ''Foo' does not have a primary key and can not be updated
Here are the docs on the primary key. I'm probably not setting it correctly:
http://realm.io/docs/cocoa/0.85.0/api/Classes/RLMObject.html#//api/name/primaryKey
Latest docs are here now: https://realm.io/docs/objc/latest/api/Classes/RLMObject.html#//api/name/primaryKey
Solution 1:[1]
As of Realm Swift v10.10.0, you declare a primary key with @Persisted(primaryKey: true):
class Foo: Object {
@Persisted(primaryKey: true) var id = 0
@Persisted var title = ""
}
Older versions:
primaryKey needs to be a class function which returns the name of the property which is the primary key, not an instance method which returns the value of the primary key.
@objcMembers class Foo: RLMObject {
dynamic var id = 0
dynamic var title = ""
override class func primaryKey() -> String? {
return "id"
}
}
Solution 2:[2]
The return type of primaryKey() is optional:
class Foo: RLMObject {
dynamic var id = 0
dynamic var title = ""
override class func primaryKey() -> String? {
return "id"
}
}
Solution 3:[3]
For Swift 5:
import RealmSwift
class Signature: Object {
@objc dynamic var id = ""
override static func primaryKey() -> String? {
return "id"
}
}
To avoid: Terminating app due to uncaught exception 'RLMException', reason: 'Primary key property 'id' does not exist on object.
Solution 4:[4]
Realm 10.12.0 & Swift 5
Legacy property declarations using @objc:
import RealmSwift
class Signature: Object {
@objc dynamic var id = ""
override static func primaryKey() -> String? {
return "id"
}
}
When using @Persisted, use @Persisted(primaryKey: true) instead:
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
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | CherryKuczery |
| Solution 3 | Maria Ortega |
| Solution 4 | Mahdi Moqadasi |
