Search code examples
iosswiftrealmprimary-key

In realm When ever i am updating it is updating only in 0th index how to solve it?


in realm i given id = 0 and it is as primary key and it will be auto increment, but problem is while updating it is saving in the index path 0 as declare as id : Int = 0.

Where ever i update also it is only updating in 0th index only.

i want to update as per selected object.

What to do?

Program :-

class Discount: Object {


    @objc dynamic var id : Int = 0

    @objc dynamic var offerName : String = ""
    @objc dynamic var percentage: Float = 0.00
    @objc dynamic var segmentIndex : Int = 0
    @objc dynamic var dateWise: Date?


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


   //Incrementa ID
    func IncrementaID() -> Int{
        let realm = try! Realm()
        if let retNext = realm.objects(Discount.self).sorted(byKeyPath: "id").last?.id {
            return retNext + 1
        }else{
            return 1
        }
    }
}

Solution

  • Generally speaking, auto-incrementing primary keys are challenging to deal with and can cause headaches long term.

    What's generally most important is ensuring primary keys are unique and using UUID strings is ideally suited for that.

    class Discount: Object {
        @objc dynamic var discount_id = UUID().uuidString
    
        override static func primaryKey() -> String? {
            return "discount_id"
        }
    }
    

    There may be concern about ordering and often times that managed by either adding a class var to determine ordering; like a timestamp for example or if you want to preserve ordering, objects can be added to a List, which keeps the order, like an array.

    To answer your specific question, the code in your question is not complete (it was partially pulled from another question). The reason is that for each object that's created, it must be written to realm first, then the next object's primary key is based on the prior object.

    Here's an example.

    @objcMembers class User: Object {
       dynamic var uid: Int = 0
       dynamic var username: String?
    
        func getNextUid() -> Int {
            let realm = try! Realm()
            if let lastObject = realm.objects(User.self).sorted(byKeyPath: "uid").first {
                let lastUid = lastObject.uid
                let nextUid = lastUid + 1
                return nextUid
            }
    
            return 1
        }
    
        override static func primaryKey() -> String? {
            return "uid"
        }
    }
    

    now the sequence to use this is as follows

    let u0 = User()
    u0.uid = u0.getNextUid()
    u0.username = "User 0"
    
    let realm = try! Realm()
    try! realm.write {
        realm.add(u0)
    }
    
    let u1 = User()
    u1.uid = u1.getNextUid()
    u1.username = "User 1"
    
    try! realm.write {
        realm.add(u1)
    }
    

    as you can see, each object needs to be written to realm in order to the next object to be queried to get the prior objects primary key.

    It's a whole lot of potentially unnecessary work and code.

    My advice: Stick with the UUID().uuidString for primary keys.