Comment définir une key d'incrémentation automatique dans Realm?

J'ai un msgid unique pour chaque object ChatData.

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

Mais chaque fois que je crée un nouvel object, je dois interroger tous les objects et get le dernier msgid.

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

Existe-t-il un moyen efficace de replace cette implémentation?

Le royaume n'a pas de comportement d'incrémentation automatique, vous devrez donc le gérer vous-même. Une question que je vous encourage à vous poser à propos de vos données:

Est-il nécessaire d'avoir des ID séquentiels, contigus et entiers?

Si ce n'est pas le cas, une key primaire de string unique peut suffire. Ensuite, vous pouvez utiliser quelque chose comme [[NSUUID UUID] UUIDSsortingng] pour générer des ID de string uniques. La bonne chose à ce sujet est que ces UUID sont plus ou less garantis d'être unique, même dans des scénarios multithread.

Si c'est le cas, il peut être plus efficace de toujours conserver le dernier numéro en memory, de sorte que les requêtes ne sont pas nécessaires chaque fois qu'un nouvel identifiant doit être généré. Si des objects peuvent être créés dans plusieurs threads, veillez à rendre votre fonction nextPrimaryKey() thread-safe, sinon elle pourrait générer le même nombre deux fois (ou plus!).

Autoincrement id Realm dans Swift 2.0: insert le code dans le domaine de class et l'utilisation d'écriture d'object

 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() -> Ssortingng? { 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 } } 

dans le file écrire l'utilisation:

 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]) }) 

Vous utilisez ce code pour la key primaire incrémentielle automatique dans Swift:

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

J'ai utilisé un creationDate dans mon model, j'ai donc créé un timeStamp Unix basé sur cette date, et l'ai utilisé comme primaryKey de mon object.

Il est garanti à 99,99% d'être unique dans mon cas (car l'horodatage est précis à la seconde), mais cela peut dépendre de votre cas d'utilisation. C'est less robuste qu'un UUID, mais dans de nombreux cas c'est suffisant.

 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 } } 

C'est essentiellement ce qui est suggéré dans la réponse de jpsim, en utilisant UUID pour générer des keys uniques. Nous interrogeons avant d'insert pour assurer l'unicité. Cela n'entraînera le plus souvent qu'une seule requête; dans le cas très rare d'une collision, il continuera jusqu'à ce qu'il trouve un identifiant unique. Cette solution est une extension naturelle sur le type Realm et est générique sur les classs qui hérite de Object . La class doit implémenter primaryKey et renvoyer le nom d'une propriété Ssortingng .

 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: Ssortingng var existing: T? = nil repeat { id = UUID().uuidSsortingng existing = object(ofType: type, forPrimaryKey: id) } while (existing != nil) let value = [ primaryKey: id ] return create(type, value: value, update: false) } } 

Dans Realm, vous devez gérer l'auto-ID ID lui-même afin qu'il y ait plusieurs façons de le gérer. Voici quelques-uns d'entre eux.

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

appelez cette méthode à chaque fois que vous ajoutez un logging.