web-dev-qa-db-fra.com

Utilisation d'énum comme propriété du modèle de domaine

Est-il possible d'utiliser un Enum comme propriété pour mon modèle? J'ai actuellement une classe comme celle-ci:

class Checkin: RLMObject {
  dynamic var id: Int = 0
  dynamic var kind: String = "checked_in"
  var kindEnum: Kind = .CheckedIn {
    willSet { self.kind = newValue.rawValue }
  }

  enum Kind: String {
    case CheckedIn = "checked_in"
    case EnRoute = "en_route"
    case DroppedOff = "dropped_off"
  }
  ....
}

Cela fonctionne bien, mais j'aimerais pouvoir avoir la propriété kind comme Enum et que Realm appelle automatiquement .rawValue sur la propriété lors de l'enregistrement d'un objet dans le magasin. Est-ce possible dans Realm ou existe-t-il déjà une demande de fonctionnalité pour cela?

59
Dave Long

Vous devez remplacer le setter et le getter de votre kindEnum dans ce cas:

enum Kind: String {
  case CheckedIn
  case EnRoute
  case DroppedOff
}

class Checkin: Object {
  @objc dynamic var id = 0
  var kind = Kind.CheckedIn.rawValue
  var kindEnum: Kind {
    get {
      return Kind(rawValue: kind)!
    }
    set {
      kind = newValue.rawValue
    }
  }
}
91
jpsim

J'ai affiné un peu plus ce modèle.

enum Thing: String {
    case Thing1
    case Thing2
    case Thing3
}

puis dans mon objet de classe Realm:

class myClass : Object {
    private dynamic var privateThing = Thing.Thing1.rawValue
    var thing: Thing {
        get { return Thing(rawValue: privateThing)! }
        set { privateThing = newValue.rawValue }
    }
}

Cela nous permet d'écrire

myClassInstance.thing = .Thing1

(stockant "Thing1" dans privateThing), mais empêche la saisie de

myClassInstance.privateThing = "Thing4"

qui n'est pas une valeur valide préservant ainsi l'intégrité des données.

44
Stephen Watson

Étant donné que Realm prend en charge les énumérations Objective-C et qu'elles sont représentables par Int, vous pouvez utiliser ceci:

class Checkin: Object {
  dynamic var id: Int = 0
  dynamic var kind: Kind = .checkedIn

  @objc enum Kind: Int {
    case checkedIn
    case enRoute
    case droppedOff
  }
  ....
}

Si vous devez analyser vers/depuis String, vous pouvez utiliser un initialiseur personnalisé pour Kind et une fonction toString.

Il y a une discussion à ce sujet dans GitHub

Cela fonctionne avec Swift 3.0 et royaume 2.0.2

15
Diogo T