使用enum作为Realm模型的属性

Dav*_*ong 60 enums realm ios

是否可以使用Enum作为我的模型的属性?我目前有一个这样的课程:

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"
  }
  ....
}
Run Code Online (Sandbox Code Playgroud)

它工作正常,但我希望能够将该kind属性设置为Enum并让Realm .rawValue在将对象保存到商店时自动调用该属性.这在Realm中是否可行,或者是否已有针对它的功能请求?

jps*_*sim 90

kindEnum对于这种情况,你应该覆盖你的setter和getter:

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
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 您可以将kind变量设置为private,因此您只能使用kindEnum更改其值. (2认同)

Ste*_*son 44

我进一步完善了这个模型.

enum Thing: String {
    case Thing1
    case Thing2
    case Thing3
}
Run Code Online (Sandbox Code Playgroud)

然后在我的Realm类对象中:

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

这允许我们写

myClassInstance.thing = .Thing1
Run Code Online (Sandbox Code Playgroud)

(将"Thing1"存储到privateThing中),但阻止输入

myClassInstance.privateThing = "Thing4"
Run Code Online (Sandbox Code Playgroud)

这不是有效值,因此保留了数据完整性.


Moh*_*lah 39

Realm 10.0.0 引入了PersistableEnum协议,可以轻松保留枚举值,而无需任何第三方扩展。

enum TaskStatusEnum: String, PersistableEnum {
    case notStarted
    case inProgress
    case complete
}
// To use the enum:
class Task: Object {
    // Required enum property
    @Persisted var status = TaskStatusEnum.notStarted 
    // Optional enum property
    @Persisted var optionalTaskStatusEnumProperty: TaskStatusEnum? 
}
Run Code Online (Sandbox Code Playgroud)

  • 这应该在 2022 年被接受。 (3认同)

Dio*_*o T 15

由于Realm支持Objective-C枚举并且它们可由Int您表示,因此您可以使用:

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

  @objc enum Kind: Int {
    case checkedIn
    case enRoute
    case droppedOff
  }
  ....
}
Run Code Online (Sandbox Code Playgroud)

如果需要解析/ String可以使用自定义初始值设定项KindtoString函数.

GitHub中对此进行了讨论

这适用于Swift 3.0和Realm2.0.2


Pei*_*Pei 12

Diogo T的解决方案在 RealmSwift 的最近更新之前有效。最终,我们现在必须遵守RealmEnum协议才能成为 Realm 的托管属性Object

@objc enum MyEnum: Int, RealmEnum {
    ...
}
Run Code Online (Sandbox Code Playgroud)

或者在某个地方添加以下内容:

extension MyEnum: RealmEnum { }
Run Code Online (Sandbox Code Playgroud)

RealmSwift 文档


Har*_*jem 9

干净简单的解决方案

Realm版本>= 10.10.0可以这样做

// Define the enum
enum StatusEnum: String, PersistableEnum {
    case notStarted
    case inProgress
    case complete
}

// To use the enum:
class Task: Object {
    @Persisted var status = StatusEnum.notStarted 
}
Run Code Online (Sandbox Code Playgroud)