2015-03-18 8 views
45

Ist es möglich, eine Enum als eine Eigenschaft für mein Modell zu verwenden? Im Moment habe ich eine Klasse wie folgt aus:Verwendung von enum als Eigenschaft von Realm-Modell

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

Es funktioniert gut, aber ich möchte die kind Eigenschaft der Enum haben sein zu können und haben Realm automatisch .rawValue auf dem Grundstück aufrufen, wenn es ein Objekt ist das Speichern Zum Geschäft. Ist das in Realm möglich oder gibt es dafür bereits eine Feature-Anfrage?

Antwort

73

Sie sollten Ihre kindEnum ‚s Setter und Getter für diesen Fall außer Kraft setzen:

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

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

wird groß sein, wenn Sie diese Probe zu Ihrer offiziellen Beispiele hinzufügen könnte. – Shmidt

+0

Das ist nicht großartig. Warum können Sie das nicht tun? Http://stackoverflow.com/questions/26900302/swift-storing-states-in-coredata-with-enums (die Martin Krenek Antwort)? – Rob

+1

Sie können '@ objc'-Enums auch direkt mit Realm verwenden, aber das funktioniert nicht für Swift-Enums mit' String'-assoziierten Werten. – jpsim

28

ich dieses Modell ein wenig weiter verfeinert haben.

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

dann in meinem Realm Klassenobjekt:

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

Dies erlaubt uns,

myClassInstance.thing = .Thing1 

(Speichern "Thing1" in privateThing) zu schreiben, verhindert aber die Eingabe von

myClassInstance.privateThing = "Thing4" 

was ist kein gültiger Wert so Erhaltung der Datenintegrität.

+0

Update: Ich habe meinen ursprünglichen Code bearbeitet, weil die = "Thing1" usw. redundant ist als Swift verwendet für seinen rawValue ein String-Literal-Äquivalent des Falls, was noch besser ist, und wir können den rawValue verwenden, um den Standard festzulegen, der zuverlässiger und sauberer ist. :-) –

+0

Danke für diesen Zusatz, ich mag diese Antwort wirklich. +1 – dehlen

7

Seit Realm Unterstützung Objective-C Aufzählungen und sie sind darstellbaren Int können Sie verwenden:

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

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

Wenn Sie analysieren müssen/von String Sie eine benutzerdefinierte Initialisierer für Kind und eine toString Funktion nutzen zu können .

Es gibt eine Diskussion darüber in GitHub

Dies funktioniert mit Swift 3.0 und Realm 2.0.2

+0

Schöne Lösung, wenn Sie eine 'Int'-Enum haben, aber es nicht sehen, wie es mit einem' String' stattdessen arbeiten kann. "Kind" wird in eine Objective-C-Enumeration konvertiert, die keine benutzerdefinierten Initialisierungen oder gespeicherten Eigenschaften unterstützt. –

+0

In der Tat habe ich keine Lösung gefunden, die mit jedem Typ außer "Int" funktioniert –

Verwandte Themen