'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