How do I set a auto increment key in Realm?

余生长醉 提交于 2019-11-27 20:40:05

问题


I have a unique msgid for each ChatData object.

@interface ChatData : RLMObject
@property NSInteger msgid;
....
@end

But each time I create a new object I have to query all objects and get the last msgid.

RLMArray *all = [[ChatData allObjects] arraySortedByProperty:@"msgid" ascending:YES];
ChatData *last = [all lastObject];
ChatData *newData = [[ChataData alloc]init];
newData.msgid = last.msgid+1;

Is there an efficient way to replace this implementation?


回答1:


Realm doesn't have auto increment behavior, so you'll need to manage that yourself. A question I'd encourage you to ask yourself about your data:

Is it necessary to have sequential, contiguous, integer ID's?

If not, then a unique string primary key might be sufficient. Then you can use something like [[NSUUID UUID] UUIDString] to generate unique string ID's. The nice thing about this is that these UUID's are more or less guaranteed to be unique, even in multithreaded scenarios.

If so, it might be more efficient to always keep the last number in memory, so that queries aren't required every time a new ID should be generated. If objects might be created in multiple threads, make sure to make your nextPrimaryKey() function thread-safe, otherwise it might generate the same number twice (or more!).




回答2:


You are use this Code for Auto Incremental Primary Key in Swift :

var myvalue = realm.objects(ChatData).map{$0.id}.maxElement() ?? 0
myvalue = myvalue + 1



回答3:


Autoincrement id Realm in Swift 2.0: insert code in class realm and object write use

import Foundation
import RealmSwift

class Roteiro: Object {

dynamic var id = 0
dynamic var Titulo = ""
dynamic var Observacao = ""
dynamic var status = false
dynamic var cadastrado_dt = NSDate()

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

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

in file write use:

let Roteiro_Add = Roteiro()
    //increment auto id
    Roteiro_Add.id = Roteiro_Add.IncrementaID()

    Roteiro_Add.Titulo = TituloDest
    Roteiro_Add.Observacao = Observacao
    Roteiro_Add.status = false


    let realm = try! Realm()
    try! realm.write({ () -> Void in
        realm.add([Roteiro_Add])
    })



回答4:


In Realm you need to manage auto-inc ID it self so there are many ways to manage it. Below is some of them.

 func incrementID() -> Int {
        let realm = try! Realm()
        return (realm.objects(Person.self).max(ofProperty: "id") as Int? ?? 0) + 1
    }

call this method every time when you adding record.




回答5:


I used a creationDate in my Model, so I created a Unix timeStamp based on this date, and used it as the primaryKey of my object.

It's 99.99% guaranteed to be unique in my case (because the timestamp is precise to the second), but it may depend on your use case. It's less robust than a UUID, but in many cases it's sufficient.

extension NSDate {

    /** Returns a NSDate instance from a time stamp */
    convenience init(timeStamp: Double) {
        self.init(timeIntervalSince1970: timeStamp)
    }
}


extension Double {

    /** Returns a timeStamp from a NSDate instance */
    static func timeStampFromDate(date: NSDate) -> Double {    
        return date.timeIntervalSince1970
    }
}



回答6:


This is essentially what is suggested in jpsim's answer, using UUID to generate unique keys. We query prior to inserting to ensure uniqueness. This will most often only incur one query; in the very rare case of a collision it will continue until it finds a unique id. This solution is a natural extension on the Realm type and is generic over classes that inherits from Object. The class must implement primaryKey and return the name of a String property.

extension Realm {

    func createAutoUnique<T: Object>(_ type: T.Type) -> T {

        guard let primaryKey = T.primaryKey() else {

            fatalError("createAutoUnique requires that \(T.self) implements primaryKey()")
        }

        var id: String

        var existing: T? = nil

        repeat {

            id = UUID().uuidString

            existing = object(ofType: type, forPrimaryKey: id)

        } while (existing != nil)

        let value = [
            primaryKey: id
        ]

        return create(type, value: value, update: false)
    }
}


来源:https://stackoverflow.com/questions/26252432/how-do-i-set-a-auto-increment-key-in-realm

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!